与区域设置无关的strtod实现

我有一个库,需要解析双数字,总是使用一个点’。’ 作为小数分隔符。 不幸的是,对于这种情况,strtod()尊重可能使用不同分隔符的语言环境,因此解析可能会失败。 我不能setlocale() – 它不是线程安全的。 所以我现在正在寻找一个干净的与语言环境无关的strtod实现。 到目前为止,我已经找到了多个实现,但是所有这些实现看起来都很糟糕,或者就像坏代码一样。 有人可以为我推荐经过充分测试,工作,干净(ANSI)C的实现吗?

获取一些已知的实现(不依赖于atof ),例如使用ruby分发的实现: ruby_1_8 / missing / strtod.c 。

警告: ruby提议的实现包含错误。 我不介意gavin指出的小差异,但如果你试图解析像“0.000000000000000000000000000000000000783475”这样的东西,你将获得0.0而不是7.834750e-37(就像股票strtod()返回。)

其他方案:

 #include  #include "strtod_locale_independent.h" extern "C" double strtod_locale_independent(const char* s) { std::istringstream text( s ); text.imbue(std::locale::classic()); double result; text >> result; return result; } 

不过,我不知道这有多快。

根据上面的答案,我尝试在ruby_1_8 / missing / strtod.c中使用Ruby实现。 但是,对于某些输入,这给出了gcc内置解析器的不同答案,以及来自stdlib.h的strtod,无论是在Mac上还是在Linux平台上:

 char * endptr ; double value1 = 1.15507e-173 ; double value2 = strtod( "1.15507e-173", &endptr ) ; double value3 = test_strtod( "1.15507e-173", &endptr ) ; assert( sizeof( double ) == sizeof( unsigned long ) ) ; printf( "value1 = %lg, 0x%lx.\n", value1, *(unsigned long*)( &value1 ) ) ; printf( "value2 = %lg, 0x%lx.\n", value2, *(unsigned long*)( &value2 ) ) ; printf( "value3 = %lg, 0x%lx.\n", value2, *(unsigned long*)( &value3 ) ) ; assert( value1 == value2 ) ; assert( value1 == value3 ) ; 

打印

 value1 = 1.15507e-173, 0x1c06dace8bda0ee0. value2 = 1.15507e-173, 0x1c06dace8bda0ee0. value3 = 1.15507e-173, 0x1c06dace8bda0edf. Assertion failed: (value1 == value3), function main, file main.c, line 16. 

所以我的建议是在使用前测试所选的实现。

netlib上还有gdtoa,BSD风格许可证: http : //www.netlib.org/fp/gdtoa.tgz