C и плавающая точка

Я написал программу на 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.

Этот вопрос не касается того, как работает плавающая точка. Я знаю о проблемах. Однако я не нашел подходящего метода для ее решения.

Возможный дубликат Математика с плавающей запятой не работает?

Blaze 26.10.2018 16:55

Как вы думаете, почему здесь проблема? cJSON отправляет «24.899999999999999» в Firebase. Этого количества цифр достаточно, чтобы Firebase могла восстановить точное значение в вашем double. Если он использует тот же формат с плавающей запятой, что вполне вероятно, то, скорее всего, так и будет. Таким образом, значение в Firebase будет иметь то же значение, что и в вашем C double. Что не так с этим? Вы пишете: «Я просто хочу, чтобы число было числом, чтобы я мог сделать с ним некоторые вычисления в Firebase». Но «24,899999999999999» будет таким же числом в Firebase, как «24,9». Итак, вы достигли желаемой цели.

Eric Postpischil 26.10.2018 17:09

Теперь, возможно, у вас есть 24,9, и фактическое число в C double, которое составляет 24,89999999999999857891452847979962825775146484375, не то, что вам нужно. В этом случае у вас возникнут проблемы с работой на C еще до того, как вы перейдете к cJSON. Чтобы сохранить 24.9, вам, возможно, придется сохранить его как строку в C. Однако, даже если вы это сделаете, что произойдет, когда вы попадете в Firebase? Используется ли десятичный разделитель для арифметики или обычная 64-битная двоичная с плавающей запятой (базовая 64-битная двоичная с плавающей запятой IEEE-754)? Если он использует двоичный код, у вас просто не может быть 24,9 в нем.

Eric Postpischil 26.10.2018 17:13

Я не верю, что это дубликат. Я знаю, есть ли проблемы с представлением с плавающей запятой. Чего я еще не видел, так это решения, как их правильно отображать. Я видел рекомендации использовать круглые, потолочные, напольные и т. д. Но поплавок - это все плавающее.

Simon 27.10.2018 13:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
209
2

Ответы 2

dec24.9 является двоичным, что dec1 / 3 является десятичным: число с бесконечным количеством десятичных знаков.

Единственный способ (я знаю - могут быть реальные решения) преодолеть эту трудность - это поместить число в строку, действительно используя sprintf.

char *num = malloc(); //Large enough to contain the result or else... SEGFAULT
sprintf(&num, "%.2f", YOUR_MATH_HERE);

Я всегда использовал его так, и у меня никогда не было проблем. (также я должен признать, что мне нравится asprintf();, который также инициирует строку.)

Jean-Marc Zimmer 28.10.2018 18:33

То, что вы показали, может работать с asprintf(), но не с sprintf().

user10543939 28.10.2018 18:35

C с плавающей запятой не может этого сделать.

Что вы можете сделать, так это представить число в миллиметрах следующим образом:

int 24900

Вы будете удивлены, как часто это наиболее жизнеспособное решение, когда системы хотят выражать и передавать данные с плавающей запятой.

Думаю, мне нравится такой подход. К сожалению, больше нигде я не нашел подходящего решения. Похоже, я на правильном пути. Либо я изменяю cJSON для вывода строки без проводов, чтобы сделать, я могу отформатировать число с помощью sprintf, либо использовать число без десятичной дроби, чтобы изменить измерение. Так, например, c сантиметр становится миллиметром. Думаю, я предпочитаю подход мили.

Simon 27.10.2018 13:23

Другие вопросы по теме