Тип Single, неправильное присваивание
От: Аноним  
Дата: 23.04.05 09:11
Оценка:
Добырый день.Подскажите пожалуйста почему когда переменной присваиваю тип Single, то операции присваивания значений выполняются неправильно:
    SS = record
        iX  :integer;
        iY  :Single;
    end;
,,,
    s1.iX := 52;
    s1.iY := 5.2;


s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.

Зарание спасибо
Re: Тип Single, неправильное присваивание
От: Smirnov.Anton Россия  
Дата: 23.04.05 09:54
Оценка:
Здравствуйте, Аноним, Вы писали:
А>s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.

А>Зарание спасибо

да потому что это приближённый тип данных
то же самое с real
Re: Тип Single, неправильное присваивание
От: Anatoly Podgoretsky Эстония http://www.podgoretsky.com
Дата: 23.04.05 10:01
Оценка:
Здравствуйте, Аноним, Вы писали:
А> iY :Single;

А> s1.iY := 5.2;

А>s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.

Это число невозможно представить точно ни а одном из допустимых типов с плавающей запятой, это наиболее близкое значение к 5.2
Re: Тип Single, неправильное присваивание
От: klovetski Россия  
Дата: 23.04.05 11:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добырый день.Подскажите пожалуйста почему когда переменной присваиваю тип Single, то операции присваивания значений выполняются неправильно:

А>
А>    SS = record
А>        iX  :integer;
А>        iY  :Single;
А>    end;
А>,,,
А>    s1.iX := 52;
А>    s1.iY := 5.2;
А>


А>s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.


Читаем Help:

Fundamental real types

Type Range Significant digits Size in bytes
Real48 2.9 x 10^-39 .. 1.7 x 10^38 11-12 6

Single 1.5 x 10^-45 .. 3.4 x 10^38 7-8 4


Double 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932 19-20 10
Comp -2^63+1 .. 2^63 -1 19-20 8
Currency -922337203685477.5808.. 922337203685477.5807 19-20 8

Как и обещано, для типа Single 7 знаков даются точно.

Константин.
Re: Тип Single, неправильное присваивание
От: Dimonka Верблюд  
Дата: 25.04.05 07:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.


Когда сравниваешь числа с плавающей точкой, сравнивай их с заданной точностью:
Equal := abs(iY - 5.2) < MinimalError;

Re[2]: Тип Single, неправильное присваивание
От: SergeyL Россия  
Дата: 25.04.05 13:40
Оценка:
Здравствуйте, Dimonka, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


А>>s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.


D>Когда сравниваешь числа с плавающей точкой, сравнивай их с заданной точностью:

D>
D>Equal := abs(iY - 5.2) < MinimalError;
D>

D>

Не знаю как в дельфи, а в билдере сравнение работает нормально, если использовать float-овую константу ( 5.2f ):
 float a=5.2f;
 if(a==5.2)  ShowMessage("a==5.2"); 
 else        ShowMessage("a!=5.2"); // попадаем сюда
 if(a==5.2f) ShowMessage("a==5.2f");// и сюда
 else        ShowMessage("a!=5.2f");
Re[3]: Тип Single, неправильное присваивание
От: Dimonka Верблюд  
Дата: 25.04.05 15:09
Оценка:
Здравствуйте, SergeyL, Вы писали:

SL>Не знаю как в дельфи, а в билдере сравнение работает нормально, если использовать float-овую константу ( 5.2f ):

SL>
SL> float a=5.2f;
SL> if(a==5.2)  ShowMessage("a==5.2"); 
SL> else        ShowMessage("a!=5.2"); // попадаем сюда
SL> if(a==5.2f) ShowMessage("a==5.2f");// и сюда
SL> else        ShowMessage("a!=5.2f");
SL>


Single занимает 4 байта, а float, на сколько я понимаю, все 8. Так что их так просто не прировняешь.
Re[3]: Тип Single, неправильное присваивание
От: Аноним  
Дата: 25.04.05 15:14
Оценка: +1
Здравствуйте, SergeyL, Вы писали:

SL>Здравствуйте, Dimonka, Вы писали:


D>>Здравствуйте, Аноним, Вы писали:


А>>>s1.iY присваивается значение не 5.2 а 5.1999998093, когда присваиваю 6.3 то вместо 6.3 присваивается 6.3000001907.


D>>Когда сравниваешь числа с плавающей точкой, сравнивай их с заданной точностью:

D>>
D>>Equal := abs(iY - 5.2) < MinimalError;
D>>

D>>

SL>Не знаю как в дельфи, а в билдере сравнение работает нормально, если использовать float-овую константу ( 5.2f ):

SL>
SL> float a=5.2f;
SL> if(a==5.2)  ShowMessage("a==5.2"); 
SL> else        ShowMessage("a!=5.2"); // попадаем сюда
SL> if(a==5.2f) ShowMessage("a==5.2f");// и сюда
SL> else        ShowMessage("a!=5.2f");
SL>


Это тебе кажется.
Так сравнивать нельзя ни на дебилдере, ни на дельфях,
ти на вижуале.
Вернее можно, но результат будет не тот, что ожидается.
Ты же на самом деле никогда не сравниваешь 2 константы
в стиле

double a = 5.2;
double b = 5.2;
bool equal = (a==b); // опа, они равны :-)))


Сравнивают все же значение, полученное в результате
вычислений с неким другим значением.
В случае чисел с плавающей точкой сравнивать всегда надо с учетом некой окресности.
Re[4]: Тип Single, неправильное присваивание
От: SergeyL Россия  
Дата: 26.04.05 08:25
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Ты же на самом деле никогда не сравниваешь 2 константы

А>в стиле

А>
А>double a = 5.2;
А>double b = 5.2;
А>bool equal = (a==b); // опа, они равны :-)))
А>


А>Сравнивают все же значение, полученное в результате

А>вычислений с неким другим значением.
А>В случае чисел с плавающей точкой сравнивать всегда надо с учетом некой окресности.

Само собой, в реальной жизни точное сравнение чисел с плавающей точкой не имеет смысла.
Я только говорю что это В ПРИНЦИПЕ возможно:

 float a=2.0f;
 a*=(a+a);
 if(a==8.f) ShowMessage("a==8.f");
Re[5]: Тип Single, неправильное присваивание
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.04.05 09:27
Оценка: 7 (2)
Здравствуйте, SergeyL, Вы писали:

SL>Само собой, в реальной жизни точное сравнение чисел с плавающей точкой не имеет смысла.

SL>Я только говорю что это В ПРИНЦИПЕ возможно:
SL>
SL> float a=2.0f;
SL> a*=(a+a);
SL> if(a==8.f) ShowMessage("a==8.f");
SL>

Братан, этот пример не более полезен чем попытка вычислить предел выражения [1 / (x — const)] при x -> const при помощи поворота const на 90 градусов. Да, для const = 8 это сработает. Что, следуя твоей логике, показывает, что это В ПРИНЦИПЕ возможно.

Несомненный вред таких примеров именно в том, что они таки работают. А это стимулирует новичков распространять их за пределы области примененимости.
Еще один классный пример попытки угадать семантику по одному корректно работающему примеру:
table1:
field1
------
   **+
   *--
   -+-
   -*+

select count(*) from table1 -- В ПРИНЦИПЕ возможно:
>5
select count(+) from table1
>syntax error --ожидали 3.

Увы — select count(x) вовсе не считает количество вхождений символа 'x' в таблице .
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Тип Single, неправильное присваивание
От: SergeyL Россия  
Дата: 27.04.05 06:51
Оценка:
Здравствуйте, Dimonka, Вы писали:

D>Single занимает 4 байта, а float, на сколько я понимаю, все 8. Так что их так просто не прировняешь.


float занимает 4 байта.
Re[6]: Тип Single, неправильное присваивание
От: SergeyL Россия  
Дата: 27.04.05 07:06
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>select count(*) from table1 -- В ПРИНЦИПЕ возможно:

>>5
S>select count(+) from table1
>>syntax error --ожидали 3.
S>[/sql]
S>Увы — select count(x) вовсе не считает количество вхождений символа 'x' в таблице

Прикольные примеры.
Только у меня фокус не в повороте на 90 градусов. 5.2f — это float, а 5.2 — это double. Соответственно при сравнении (и не только) с double-овой константой float-овая переменная приводится к double.

if either operand is of type double, the other operand is converted to double

А вот (double)#.# не всегда равно (double)#.#f. Т.е в моем примере a==5.2f, но a!=5.2.
И кстати никого я не убеждал точно сравнивать float-ы. ИМХО это объяснение лучше чем просто "это приближённый тип данных".
Re[7]: Тип Single, неправильное присваивание
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.04.05 07:31
Оценка:
Здравствуйте, SergeyL, Вы писали:
SL>Прикольные примеры.
SL>Только у меня фокус не в повороте на 90 градусов. 5.2f — это float, а 5.2 — это double. Соответственно при сравнении (и не только) с double-овой константой float-овая переменная приводится к double.
Не хитри. Весь фокус у тебя в том, что ты взял числа, кратные 2. Они-то как раз представимы в IEEE формате без потерь. Благодаря этому срабатывает сравнение "а" с восьмеркой. С константами некратными 2 фокус не пройдет.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Тип Single, неправильное присваивание
От: SergeyL Россия  
Дата: 27.04.05 07:59
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Не хитри. Весь фокус у тебя в том, что ты взял числа, кратные 2. Они-то как раз представимы в IEEE формате без потерь. Благодаря этому срабатывает сравнение "а" с восьмеркой. С константами некратными 2 фокус не пройдет.


 float a=1.137f;
 a=a+a;
 if(a==2.274f) ShowMessage("ok");
Re[9]: Тип Single, неправильное присваивание
От: Danchik Украина  
Дата: 27.04.05 10:14
Оценка:
Здравствуйте, SergeyL, Вы писали:

SL>Здравствуйте, Sinclair, Вы писали:


S>>Не хитри. Весь фокус у тебя в том, что ты взял числа, кратные 2. Они-то как раз представимы в IEEE формате без потерь. Благодаря этому срабатывает сравнение "а" с восьмеркой. С константами некратными 2 фокус не пройдет.


SL>
SL> float a=1.137f;
SL> a=a+a;
SL> if(a==2.274f) ShowMessage("ok");
SL>


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

Для того что бы не терялся precision в базах данных используется BCD тип. Почитай себе на досуге что это такое и зачем это сделано...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.