_4afc_ 25 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 9 minutes ago, Метценгерштейн said: под АРМ, но с проверкой на х64. Т.е. хотелось бы алгоритм, работающий одинаково. Одинаково неверное слово для плавающей точки... Conversion of floating-point to unsigned integer Quote On the ARM architecture, conversion of a floating-point value to a 32-bit integer saturates to the nearest value that the integer can represent if the floating-point value is outside the range that the integer can represent. On the x86 and x64 architectures, the conversion wraps around if the integer is unsigned, or is set to -2147483648 if the integer is signed. None of these architectures directly support the conversion of floating-point values to smaller integer types; instead, the conversions are performed to 32 bits, and the results are truncated to a smaller size. For the ARM architecture, the combination of saturation and truncation means that conversion to unsigned types correctly saturates smaller unsigned types when it saturates a 32-bit integer, but produces a truncated result for values that are larger than the smaller type can represent but too small to saturate the full 32-bit integer. Conversion also saturates correctly for 32-bit signed integers, but truncation of saturated, signed integers results in -1 for positively-saturated values and 0 for negatively-saturated values. Conversion to a smaller signed integer produces a truncated result that's unpredictable. For the x86 and x64 architectures, the combination of wrap-around behavior for unsigned integer conversions and explicit valuation for signed integer conversions on overflow, together with truncation, make the results for most shifts unpredictable if they are too large. These platforms also differ in how they handle conversion of NaN (Not-a-Number) to integer types. On ARM, NaN converts to 0x00000000; on x86 and x64, it converts to 0x80000000. Floating-point conversion can only be relied on if you know that the value is within the range of the integer type that it's being converted to. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 63 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 2 часа назад, Метценгерштейн сказал: f = atof("2.86"); возвращает 2.8599999 Причем, это если гоню по большому масиву. Если просто локально вызвать один раз, то нормально 2.86 дает Сделайте f = atof("2.86F"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Метценгерштейн 0 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 21 minutes ago, HardEgor said: Сделайте f = atof("2.86F"); без результата Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 3 hours ago, Метценгерштейн said: f = atof("2.86"); возвращает 2.8599999 Причем, это если гоню по большому масиву. Если просто локально вызвать один раз, то нормально 2.86 дает f- double вижуал студия в отладчике может что угодно показывать, и как угодно округлять но число 2.86 нельзя представить в виде суммы степеней 2, ни с одинарной ни с двойной точностью. http://www.binaryconvert.com/result_float.html?decimal=050046056054 http://www.binaryconvert.com/result_double.html?decimal=048050046056054 можно либо 2.86000000000000031974423109205 либо 2.85999999999999987565502124198 так вот второе число ближе к 2.86 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Grigorij 0 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба И в догонку к предыдущему ответу. Решение проблем (если именно такое точно представление требуется) - использование чисел с фиксированной запятой (и соответствующей математики). Про данный тип чисел море статей, которые легко находятся в гугле, а на том же GitHub можно и готовые библиотеки найти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба https://www.onlinegdb.com/online_c_compiler дает ровно 2.86. Keil тоже дает такой же результат P.S. Кстати, если явно в printf() задать точность (количество знаков после запятой) в ⩽ 16, то будет отписываться 2.86000... Стоит увеличить это количество до 17 (%.17f), сразу печатается результат 2.85999... Что, на мой взгляд, логично. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Grigorij 0 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 13 minutes ago, Arlleex said: дает ровно 2.86. Keil тоже дает такой же результат Все что показывает отладчик (Keil, IAR, MSVS и т.д.) - это все на усмотрение разработчиков конкретных сред и то, как они округляют число при выводе. Выше уже написали, что далеко не все вещественные числа можно точно представить с использованием float или double. И здесь нет никакой магии, просто особенность стандарта и способа представления таких чисел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 1 час назад, Grigorij сказал: Выше уже написали, что далеко не все вещественные числа можно точно представить с использованием float или double. И здесь нет никакой магии, просто особенность стандарта и способа представления таких чисел. Я знаю Мой пост акцентировал внимание на то, что ответ и в отладчике может быть двояким. FP-числа в принципе не предназначены для позиционного точного вывода как есть (по десятичным знакам). Оптимально (как Вы уже сказали) применять арифметику с фиксированной точкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 2 марта, 2020 Опубликовано 2 марта, 2020 · Жалоба 3 hours ago, Метценгерштейн said: без результата Если уж "запутались в нулях", то то, что Вы видите в читабельно-десятичной форме - это отображение двоичного плавающего числа. (что по printf, что в отладчике). И если надо сравнивать - сравнивайте-смотрите не визуализацию, а области памяти, где эти числа лежат (то что в массиве и то что нет). Хотя смысла такое сравнение не имеет. Можно использовать для ввода sscanf (более медленно, но очень удобно). Функция возвращает кол-во успешно "распознанных" чисел. Если ошибка - соотв-но получите 0. Есть шаблоны ввода, вроде "любая цифра", набор символов "abcde" итд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 марта, 2020 Опубликовано 3 марта, 2020 · Жалоба ps, извиняюсь не (совсем) в тему, но Если есть возможность жестко ограничить формат ввода для float - сделайте это. Чтобы не пришлось вводить "хвосты" 1.3333333(3). Все что зашкаливает за разумный и заранее предусмотренный предел - в ошибку. Для отладки ввода, прототипа, посмотрите sscanf. char *m0 = new char [100]; . . . . CString cs0; . . . while (my_cfg_MAP.ReadString(my_cfg_MAP.pBufPtr, 1024)) { cs0 = my_cfg_MAP.pBufPtr; ... проверки входной строки на допустимость по шаблонам . . . // "разобрать" строку по шаблону, разделители колонок в данном случае запятая и двоеточие // пробелы итд сжаты. int n_1 = sscanf( cs0,"%[^,],%[^,],:%[^:]:,:%[^:]:,%[^,],%s", m0, m1, m2, m3, m4, m5); if(n_1 != 6 ) { AfxMessageBox("sort.cfg file error format !"); AfxMessageBox(cs0); . . . } . . . . . }//w два в одном - проверка на соответствие шаблону, и ввод. n = sscanf(dev_name, "//UDP:%[.0123456789]:%[012345678]/%s", ip_udp, port_udp, &ser_udp[1]); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться