Я написал программу на C и Im, используя cJSON для инкапсуляции данных и отправки в Firebase.
Я просто хочу, чтобы число было числом, чтобы я мог сделать с ним некоторые вычисления в Firebase.
Вот где это становится беспорядком.
double 24.9
Это возвращает
24.899999999999999
Так, например,
round((399 / 16.0) * 10.0) / 10.0 = 24.8999999
Мне нужен только один десятичный знак, я хочу 24,9, мне нужно, чтобы оно было представлено в виде числа. Похоже, мне просто нужно выполнить sprintf () и использовать RAW в cJSON. Если в C нет другого способа сохранить мои 24,9 равными 24,9.
Этот вопрос не касается того, как работает плавающая точка. Я знаю о проблемах. Однако я не нашел подходящего метода для ее решения.
Как вы думаете, почему здесь проблема? cJSON отправляет «24.899999999999999» в Firebase. Этого количества цифр достаточно, чтобы Firebase могла восстановить точное значение в вашем double. Если он использует тот же формат с плавающей запятой, что вполне вероятно, то, скорее всего, так и будет. Таким образом, значение в Firebase будет иметь то же значение, что и в вашем C double. Что не так с этим? Вы пишете: «Я просто хочу, чтобы число было числом, чтобы я мог сделать с ним некоторые вычисления в Firebase». Но «24,899999999999999» будет таким же числом в Firebase, как «24,9». Итак, вы достигли желаемой цели.
Теперь, возможно, у вас есть 24,9, и фактическое число в C double, которое составляет 24,89999999999999857891452847979962825775146484375, не то, что вам нужно. В этом случае у вас возникнут проблемы с работой на C еще до того, как вы перейдете к cJSON. Чтобы сохранить 24.9, вам, возможно, придется сохранить его как строку в C. Однако, даже если вы это сделаете, что произойдет, когда вы попадете в Firebase? Используется ли десятичный разделитель для арифметики или обычная 64-битная двоичная с плавающей запятой (базовая 64-битная двоичная с плавающей запятой IEEE-754)? Если он использует двоичный код, у вас просто не может быть 24,9 в нем.
@EricPostpischil Firebase, похоже, не использует десятичную дробь
Я не верю, что это дубликат. Я знаю, есть ли проблемы с представлением с плавающей запятой. Чего я еще не видел, так это решения, как их правильно отображать. Я видел рекомендации использовать круглые, потолочные, напольные и т. д. Но поплавок - это все плавающее.





dec24.9 является двоичным, что dec1 / 3 является десятичным: число с бесконечным количеством десятичных знаков.
Единственный способ (я знаю - могут быть реальные решения) преодолеть эту трудность - это поместить число в строку, действительно используя sprintf.
char *num = malloc(); //Large enough to contain the result or else... SEGFAULT
sprintf(&num, "%.2f", YOUR_MATH_HERE);
C с плавающей запятой не может этого сделать.
Что вы можете сделать, так это представить число в миллиметрах следующим образом:
int 24900
Вы будете удивлены, как часто это наиболее жизнеспособное решение, когда системы хотят выражать и передавать данные с плавающей запятой.
Думаю, мне нравится такой подход. К сожалению, больше нигде я не нашел подходящего решения. Похоже, я на правильном пути. Либо я изменяю cJSON для вывода строки без проводов, чтобы сделать, я могу отформатировать число с помощью sprintf, либо использовать число без десятичной дроби, чтобы изменить измерение. Так, например, c сантиметр становится миллиметром. Думаю, я предпочитаю подход мили.
Возможный дубликат Математика с плавающей запятой не работает?