Вы можете использовать modf
для разделения целых и дробных частей. Затем вы можете умножить дробную часть на 1.0e17
и вызвать floor
для правильного округления результатов до целочисленного компонента, а затем привести к unsigned long
(дробная часть никогда не будет отрицательной, и это позволит вам максимизировать количество бит в целочисленном типе). Наконец, запустите цикл, чтобы обрезать нули на unsigned long
. Например:
inline static string StringFromNumber(double val)
{
double intpart, fracpart;
fracpart = round((modf(val, &intpart)) * 1.0e17);
long int_long = static_cast<long>(intpart);
unsigned long frac_long = static_cast<long>(fracpart);
//trim off the zeros
for(unsigned long divisor = 10;;divisor *= 10)
{
if ((frac_long / divisor) * divisor != frac_long)
{
frac_long = frac_long / (divisor / 10);
break;
}
}
//...more code for converting to string
}
Обратите внимание, что этот код будет работать только до 17 десятичных знаков, если вы работаете на 64-битной платформе, а unsigned long
определен как 64-битный целочисленный тип. В противном случае вы захотите изменить unsigned long
на uint64_t
. Также имейте в виду, что, поскольку числа с плавающей запятой являются приблизительными, а множитель равен 1.0e17
, значение fracpart
может не совпадать со значением части-части val
... другими словами, некоторые дополнительные цифры после любого необходимого округления.