Перейти к содержанию
    

стринг в число с плавающей точкой преобразовать

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.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Метценгерштейн сказал:

f = atof("2.86"); 

возвращает 2.8599999

Причем, это если гоню по большому масиву. Если просто локально вызвать один раз, то нормально 2.86 дает

Сделайте f = atof("2.86F");

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 minutes ago, HardEgor said:

Сделайте f = atof("2.86F");

image.png.84d5017631610eaf259f4ae54390d078.png

без результата

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, Метценгерштейн said:

f = atof("2.86");

возвращает 2.8599999

Причем, это если гоню по большому масиву. Если просто локально вызвать один раз, то нормально 2.86 дает

image.thumb.png.9f8bdb0defbaa2a99ba702a8132a4470.png

image.png.9bf4023544762649718e4cfa7e809ef3.png

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И в догонку к предыдущему ответу. Решение проблем (если именно такое точно представление требуется) - использование чисел с фиксированной запятой (и соответствующей математики). Про данный тип чисел море статей, которые легко находятся в гугле, а на том же GitHub можно и готовые библиотеки найти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

https://www.onlinegdb.com/online_c_compiler дает ровно 2.86.

Keil тоже дает такой же результат:wink:

image.png.90263bbc11877a671a6f812843c69831.png

 

P.S. Кстати, если явно в printf() задать точность (количество знаков после запятой) в ⩽ 16, то будет отписываться 2.86000...

Стоит увеличить это количество до 17 (%.17f), сразу печатается результат 2.85999... Что, на мой взгляд, логично.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 minutes ago, Arlleex said:

дает ровно 2.86.

Keil тоже дает такой же результат:wink:

Все что показывает отладчик (Keil, IAR, MSVS и т.д.) - это все на усмотрение разработчиков конкретных сред и то, как они округляют число при выводе. Выше уже написали, что далеко не все вещественные числа можно точно представить с использованием float или double. И здесь нет никакой магии, просто особенность стандарта и способа представления таких чисел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Grigorij сказал:

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

Я знаю:yes3: Мой пост акцентировал внимание на то, что ответ и в отладчике может быть двояким.

FP-числа в принципе не предназначены для позиционного точного вывода как есть (по десятичным знакам).

Оптимально (как Вы уже сказали) применять арифметику с фиксированной точкой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, Метценгерштейн said:

image.png.84d5017631610eaf259f4ae54390d078.png

без результата

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

(что по printf, что в отладчике). И если надо сравнивать - сравнивайте-смотрите не визуализацию, а области памяти, где эти числа лежат (то что в массиве и то что нет). Хотя смысла такое сравнение не имеет.

Можно использовать для ввода sscanf (более медленно, но очень удобно). Функция возвращает кол-во успешно "распознанных" чисел.

Если ошибка - соотв-но получите 0. Есть шаблоны ввода, вроде "любая цифра", набор символов "abcde" итд.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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]);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...