Математический форум Math Help Planet http://mathhelpplanet.com/ |
|
Проблема с числами с плавающей запятой http://mathhelpplanet.com/viewtopic.php?f=44&t=55188 |
Страница 1 из 1 |
Автор: | dersu-uzalah [ 05 июл 2017, 10:14 ] |
Заголовок сообщения: | Проблема с числами с плавающей запятой |
Всем здравствуйте. Есть некая прога, написанная на С, в которой интенсивно используются числа с плавающей запятой в формате IEEE64. Прога написана для микроконтроллера семейства HCS08 Freescale. Для написания и компиляции использовалась среда CodeWarrior IDE ver.5.9.0. Думаю что это не имеет значения. На определенном этапе было замечено, что происходит искажение чисел, значение которых превышает 65536. Например, 65535,9999 таким и остается, а 65536 само по себе превращается в 65536.0004. Чем больше число, тем больше искажение. Все в сторону увеличения. Код примерно такой: double a; a = 65535,9999; OutLCD (a); a+=0.0001; OutLCD (a); При первом выводе на дисплей получаем ожидаемое 65535,9999 А при 2-м: 65536.0004 В системе имеется файл float.h (прилагается), который вроде как задает конфигурацию чисел с плавающей запятой. Может есть смысл поиграться с его настройками? Буду бесконечно признателен за любые идеи, в чем проблема, и как это можно было бы победить. PS. Файл не добавляется почему-то, копирую его сюда: /***************************************************** float.h - ANSI-C library: floating point format ---------------------------------------------------- Copyright (c) Metrowerks, Basel, Switzerland All rights reserved Do not modify! *****************************************************/ #ifndef _H_FLOAT_ #define _H_FLOAT_ #ifdef __cplusplus extern "C" { #endif #if !defined(__HIWARE__) && defined(__MWERKS__) && defined(__PPC__) /* Metrowerks PowerPC compiler does not define the stuff below */ #define __FLOAT_IS_IEEE32__ #define __DOUBLE_IS_IEEE64__ #endif /**** Rounding Mode */ #define FLT_ROUNDS -1 #define FLT_RADIX 2 /**** float */ #ifdef __FLOAT_IS_IEEE32__ #define FLT_MANT_DIG 24 #define FLT_DIG 6 #define FLT_MIN_EXP -126 #define FLT_MIN_10_EXP -37 #define FLT_MAX_EXP 127 #define FLT_MAX_10_EXP 38 #define FLT_MAX 3.402823466E+38F #define FLT_EPSILON 1.19209290E-07F #define FLT_MIN 1.17549435E-38F #endif #ifdef __DOUBLE_IS_IEEE32__ /**** double */ #define DBL_MANT_DIG FLT_MANT_DIG #define DBL_DIG FLT_DIG #define DBL_MIN_EXP FLT_MIN_EXP #define DBL_MIN_10_EXP FLT_MIN_10_EXP #define DBL_MAX_EXP FLT_MAX_EXP #define DBL_MAX_10_EXP FLT_MAX_10_EXP #define DBL_MAX FLT_MAX #define DBL_EPSILON FLT_EPSILON #define DBL_MIN FLT_MIN #endif #ifdef __DOUBLE_IS_IEEE64__ /**** double */ #define DBL_MANT_DIG 53 #define DBL_DIG 15 #define DBL_MIN_EXP -1022 #define DBL_MIN_10_EXP -307 #define DBL_MAX_EXP 1023 #define DBL_MAX_10_EXP 308 #define DBL_MAX 1.7976931348623157E+308 #define DBL_EPSILON 2.2204460492503131E-16 #define DBL_MIN 2.2259738585972014E-308 #endif #ifdef __FLOAT_IS_DSP__ /* DSP float */ #define FLT_MANT_DIG 16 #define FLT_DIG 4 #define FLT_MIN_EXP -32768 #define FLT_MIN_10_EXP -9863 #define FLT_MAX_EXP 32767 #define FLT_MAX_10_EXP 9863 #define FLT_MAX 0.9999695E+9863F #define FLT_EPSILON 3.051757E-05F #define FLT_MIN 0.9999695E+9863F #endif #ifdef __DOUBLE_IS_DSP__ /**** double */ #define DBL_MANT_DIG 16 #define DBL_DIG 4 #define DBL_MIN_EXP -32768 #define DBL_MIN_10_EXP -9863 #define DBL_MAX_EXP 32767 #define DBL_MAX_10_EXP 9863 #define DBL_MAX 0.9999695E+9863F #define DBL_EPSILON 3.051757E-05F #define DBL_MIN 0.9999695E+9863F #endif /**** long double */ #define LDBL_MANT_DIG DBL_MANT_DIG #define LDBL_DIG DBL_DIG #define LDBL_MIN_EXP DBL_MIN_EXP #define LDBL_MIN_10_EXP DBL_MIN_10_EXP #define LDBL_MAX_EXP DBL_MAX_EXP #define LDBL_MAX_10_EXP DBL_MAX_10_EXP #define LDBL_MAX DBL_MAX #define LDBL_EPSILON DBL_EPSILON #define LDBL_MIN DBL_MIN #ifdef __cplusplus } #endif #endif /*****************************************************/ /* end float.h */ |
Автор: | SAVANTOS [ 05 июл 2017, 22:04 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Вы можете поменять компилятор или другой микроконтроллер и попробовать свою программу снова? Ошибка может быть по многим причинам. Я не сильно разбираюсь в микроконтроллерах, но может быть это аппаратная ошибка или компилятор генерирует неправильные инструкции для процессора. Редактировать файлы из стандартной библиотеки не рекомендую. |
Автор: | dersu-uzalah [ 05 июл 2017, 22:23 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Спасибо за Ваш ответ, SAVANTOS. На другом микроконтроллере (и соответственно с другим компилятором) все работает как надо. Но мне нужно чтобы именно на этом работало. Файлы из стандартной библиотеки всегда можно вернуть в исходное состояние. Однако таким путем мне не удалось ничего добиться. |
Автор: | bimol [ 05 июл 2017, 22:27 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Такой вариант, заменить a+=0.0001; на double b b=0.0001; a+=b; |
Автор: | Xmas [ 05 июл 2017, 23:39 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Не помешает проверить, установлен ли флажок на 32-битные "плавающие точки". Однажды на каком-то компиляторе встречал "по умолчанию" 24-битные плавающие. Нужно было явно указывать -DIEEE32 или типа того, чтобы включилось полномасштабное вычисление. |
Автор: | SAVANTOS [ 06 июл 2017, 10:06 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Нашёл похожую проблему на форуме NXP. Там говорится, что при создании проекта есть выбор-какой формат использовать для типов float и double. У вас было что-то похожее? Скорее всего такие ошибки из-за того что используется одинаковый формат представления для float и double. https://community.nxp.com/thread/383411 |
Автор: | dersu-uzalah [ 06 июл 2017, 13:33 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
bimol, я показал здесь лишь простейший пример. На самом деле оно всегда добавляет эти свои 0.0004 Xmas, при создании проекта все флажки были установлены как надо: double - IEEE64 SAVANTOS, это я пытался что-то у них выяснить, но такой "обход" как они предлагают, мне не подходит. Всем спасибо! |
Автор: | bimol [ 06 июл 2017, 14:18 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Я к тому, что все константы надо объявлять через переменные double или явно указывать, что константа double Иначе проблема зарыта глубоко. |
Автор: | dersu-uzalah [ 11 июл 2017, 07:51 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
Выяснились подробности. double val1; double val2; val1 = 65535.9999; val2 = 65536.0000; sprintf (lbuf,"%5.4f", val1); sprintf (lbuf,"%5.4f", val2); После выполнения 1-го sprintf, в lbuf[] заносится строка "65535.9999", после выполнения 2-го: "65536.0004" |
Автор: | Xmas [ 11 июл 2017, 09:15 ] |
Заголовок сообщения: | Re: Проблема с числами с плавающей запятой |
dersu-uzalah Очень похоже на баг компилятора. В 65536.000 вообще неоткуда взяться 0.0004 - у этого числа в двоичном плавающем формате в мантиссе одни нули и ничего кроме нулей. Так что Вы тут ни при чём. Это всё компилятор. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |