我正在尝试将字符串转换为双精度浮点数,但由于我正在开发一个Windows本地应用程序(仅链接到ntdll.dll),因此我没有大部分标准库可用。我可以使用math.h中的基本FP支持,但那基本上就是这样了。
如何将字符串转换为最接近该字符串表示的有理数的双精度浮点数?
如何将字符串转换为最接近该字符串表示的有理数的双精度浮点数?
如果您真的想要得到最接近的结果,这个问题相当困难,需要使用任意精度算术才能实现。例如,请参见ftp://ftp.ccs.neu.edu/pub/people/will/howtoread.ps。
假设JSON语法(链接目前无法访问,这里是Google缓存版本)对您来说是可接受的,下面的内容基本上直接来自于内部开发的JSON解析代码,是其语法图的文字实现:
/*
defined functions for handling the input:
nextChar() - peeks at the next character of input
getAndRemoveCharacter() - returns the next character of input and
dequeues it
This code also assumes you have BOOL, YES and NO defined; I've left this in
for clarity
*/
double getNumber()
{
// determine whether the number is negative - it'll start with a '-' if so
BOOL negative = NO;
if(nextChar() == '-')
{
negative = YES;
getAndRemoveCharacter();
}
// seed the output number to 0
double number = 0.0;
// if the next character isn't a '0' then this is the number proper, so
// just pull off the digits and assemble the number; otherwise this number
// is either 0 itself (in which case the initial seed is correct) or a
// decimal starting in 0
if(nextChar() != '0')
{
while(nextChar() >= '0' && nextChar() <= '9')
{
number *= 10.0;
number += getAndRemoveCharacter() - '0';
}
}
else
getAndRemoveCharacter();
// if this is a decimal then jump on to the decimal part and deserialise
// digits, much as above
if(nextChar() == '.')
{
getAndRemoveCharacter();
double decimalMultiplier = 1.0;
while(nextChar() >= '0' && nextChar() <= '9')
{
decimalMultiplier /= 10.0;
number += (double)(getAndRemoveCharacter() - '0') * decimalMultiplier;
}
}
// if this number has an exponent then deal with that
if(nextChar() == 'e' || nextChar() == 'E')
{
getAndRemoveCharacter();
double exponent = 0.0;
BOOL exponentPositive = YES;
// JSON allows positive exponents to start with + (unlike
// the mantissa) and requires negative exponents to start with -
if(nextChar() == '+')
{
getAndRemoveCharacter();
}
else
if(nextChar() == '-')
{
exponentPositive = NO;
getAndRemoveCharacter();
}
// read out digits and assemble exponent
while(nextChar() >= '0' && nextChar() <= '9')
{
exponent *= 10.0;
exponent += getAndRemoveCharacter() - '0';
}
// apply exponent
number *= pow(10.0, exponentPositive ? exponent : -exponent);
}
// negate if necessary and return
return negative ? -number : number;
}
任何将ASCII字母放在正常ASCII范围内的字符类型都可以使用,因此它应该在ASCII和变体以及Unicode上同样有效。我猜你可能只想直接将字符串作为参数传递,而不是进行所有这些调用;它们在原始代码中存在,因为输入流来自远方,所以它们可能会阻塞。
'pow'中使用的仅有的math.h函数,其他都是基本操作。