Форум: "Потрепаться";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];
ВнизНеожиданное открытие? Найти похожие ветки
← →
olookin © (2005-01-16 00:07) [0]Всегда думал, что дельфям все равно, какое значение переменной приравнивается. Т.е. я имею в виду, что если:
d: double;
d:=10;
равно тому же, что и:
d: double;
d:=10.0;
Сейчас получил, что это не так. Получил настолько очевидно, что нет сомнений. Значит, преобразование типов важно и в паскале?
← →
olookin © (2005-01-16 00:10) [1]Да, вопрос еще кстати. В Си++ приравнивание double a=0 и double a=0.0 равносильно? Если нет, то надо ли учитывать это при сравнении типа:
if(a==0)
или
if(a==0.0)
?
← →
palva © (2005-01-16 00:18) [2]
{$APPTYPE CONSOLE}
var
d, e: Double;
begin
d := 0;
e := 0.0;
if d = e then writeln("Совпадает")
else writeln("Не совпадает")
end.
У меня выдает "Совадает"
← →
palva © (2005-01-16 00:20) [3]Ну конечно, надо не 0, а 10. Поторопился. Но тоже совпадает.
{$APPTYPE CONSOLE}
var
d, e: Double;
begin
d := 10;
e := 10.0;
if d = e then writeln("Совпадает")
else writeln("Не совпадает")
end.
← →
jack128 © (2005-01-16 00:20) [4]olookin © (16.01.05 0:10) [1]
if(a==0.0)
и то и другое лудше не использовать. Обычно пишут if (abs(a) < 0.000001) {};
← →
olookin © (2005-01-16 00:26) [5][4] jack128 © (16.01.05 00:20)
Согласен. Но не до такой же степени:
procedure Some(t: double);
begin
if t<0 then ShowMessage("Бред");
end;
procedure SomeForSome;
begin
somevalue:=0.00001;
for i:=0 to 10000 do
Some(somevalue*i/1000); //получаем "Бред"
for i:=0 to 10000 do
Some(somevalue*i/1000.0); //не получаем "Бред"
end;
← →
olookin © (2005-01-16 00:28) [6]Замечу про "Бред". Положим, что я где-то чего-то не чищу или просто обращаюсь к не тому элементу памяти (ну хотя бы при неправильном обращении к элементу массива). Но почему "Бред" имеет место быть только при задании этой несчастной тысячи в виде целого? Ужели это принципиально для возникновения ошибки?
← →
palva © (2005-01-16 00:37) [7]А весь код? Чтобы компилировалось. Вот дополнил:
[code]
uses Dialogs;
var
somevalue: Double;
procedure Some(t: double);
begin
if t<0 then ShowMessage("Бред");
end;
procedure SomeForSome;
var
i: Integer;
begin
somevalue:=0.00001;
for i:=0 to 10000 do
Some(somevalue*i/1000); //получаем "Бред"
for i:=0 to 10000 do
Some(somevalue*i/1000.0); //не получаем "Бред"
end;
begin
SomeForSome;
end.
[/code]
Не получаю никакого бреда.
← →
Dok_3D © (2005-01-16 00:40) [8]olookin © (16.01.05 00:26) [5]
Ты будешь смеяться, но твой чудо-пример у меня вообще не выдал "Бред".
Правда, я немного доработал процедуру SomeForSome, чтобы закомпиляться без проблем(вставил описание переменых (var somevalue : double; i : integer;)).
Вот такие пироги ...
← →
olookin © (2005-01-16 00:42) [9][8] Dok_3D © (16.01.05 00:40)
Хм, мой пример был лишь пример... Конечно, я не исключаю невалидного обращения к памяти, но странно все же, почему смена типа меняет и результат...
← →
olookin © (2005-01-16 00:44) [10]Хорошо, что может быть причиной чисто теоретической возникновения такого рода событий? Не в моем приведенном данном примере, а в общем (но основываясь все-таки именно на моем примере, так как у меня реально выполняется в чем то аналогичная процедура)?
← →
palva © (2005-01-16 00:45) [11]Смена типа запросто может изменить результат, такие примеры мы и сами привести можем. А вот присваивание
d: double;
d:=10.0;
или
d:=10;
по-моему без разницы. Я конечно засомневался и проверил, но увы...
← →
olookin © (2005-01-16 00:52) [12][11] palva © (16.01.05 00:45)
Но тут не просто приравнивание, а передача приравненного параметра в процедуру. Может это важно?
← →
Anatoly Podgoretsky © (2005-01-16 01:47) [13]olookin © (16.01.05 00:26) [5]
Some(somevalue*i/1000); //получаем "Бред"
Some(somevalue*i/1000.0); //получаем "Бред"
Компилятор имеет право сменить порядок вычичлений, и в первом случае у тебя получится деление целого на целое, а во втором случае целого на плавающее. Поскольку у тебя используются константы, а не переменные. Замени в своем коде на переменную тиа double = 10000 и посмотри на результат.
← →
Anatoly Podgoretsky © (2005-01-16 01:49) [14]Код из olookin © (16.01.05 00:26) [5]
нельзя брать в расчет, поскольку он не откомпилируется, значит у тебя совсем другой код, а этот только для примера, в итоге у palva фокус не удался.
← →
Johnmen © (2005-01-16 01:56) [15]>olookin © (16.01.05 00:07)
>d: double;
>d:=10;
>равно тому же, что и:
>d:=10.0;
Да, это м.б. эквивалентно. Но в первом случае имеет место неявное преобразование типа. Во втором - нет.
>Сейчас получил, что это не так.
Как получил ? Что делал ?
← →
olookin © (2005-01-16 02:12) [16][15] Johnmen © (16.01.05 01:56)
olookin © (16.01.05 00:07)
Сейчас получил, что это не так.
О, это большой код, как получил - не знаю...
← →
olookin © (2005-01-16 02:13) [17][16] olookin © (16.01.05 02:12)
Поправлюсь, как получил - знаю, а вот почему получил - не знаю...
← →
olookin © (2005-01-16 02:14) [18][14] Anatoly Podgoretsky © (16.01.05 01:49)
А что там не компилируется из [5]?
← →
Anatoly Podgoretsky © (2005-01-16 02:41) [19]Не объявлены somevalue и i, если первое возможно объявлено где то там, то должно i быть локальной переменной, о чем любежно сообщил palva и также что никаких проблем у него не возникло, ни по первому, ни по второму примеру.
← →
olookin © (2005-01-16 02:53) [20][19] Anatoly Podgoretsky © (16.01.05 02:41)
Имеено так, первое объявлено "где-то там", а i является локальной переменной. Как в моем приведенном примере, так и в реальности...
← →
SPeller © (2005-01-16 05:34) [21]У нас в конторе в одном проекте для этого написали функцию для сравнения двух double чисел с нужной точностью. if FloatCompare(Var1, Var2) then ...
← →
имя (2005-01-16 10:07) [22]Удалено модератором
← →
Sergey_Masloff (2005-01-16 10:24) [23]SPeller © (16.01.05 05:34) [21]
>У нас в конторе в одном проекте для этого написали функцию для >сравнения двух double чисел с нужной точностью.
Да можно вообще всю VCL переписать. Мы ж справку не читаем - на фига нам крутым. А то
function CompareValue(const A, B: Integer): TValueRelationship; overload;
function CompareValue(const A, B: Int64): TValueRelationship; overload;
function CompareValue(const A, B: Single; Epsilon: Single = 0): TValueRelationship; overload;
function CompareValue(const A, B: Double; Epsilon: Double = 0): TValueRelationship; overload;
function CompareValue(const A, B: Extended; Epsilon: Extended = 0): TValueRelationship; overload;
← →
Григорьев Антон © (2005-01-16 10:24) [24]
> Johnmen © (16.01.05 01:56) [15]
> >olookin © (16.01.05 00:07)
> >d: double;
> >d:=10;
> >равно тому же, что и:
> >d:=10.0;
>
> Да, это м.б. эквивалентно. Но в первом случае имеет место
> неявное преобразование типа. Во втором - нет.
Преобразование типа имеет место только на этапе компиляции. Ассемблерный код получается одинаковым (проверено в Delphi 5).
← →
Zer0 © (2005-01-16 10:51) [25]прикол из жизни:
#include <stdio.h>
void myfunc(int a,int b, int c, ind d)
{ printf("\n%d %d %d %d\n",a,b,c,d);
}
void main(void)
{ int i=1;
myfunc(i++,i++,i++,i++);
printf(" %d",i);
}
Turbo C выдает
4 3 2 1
5
MS VC без оптимизации
4 3 2 1
5
MS VC c оптимизацией
1 1 1 1
5
это было самое неожиданное открытие в моей жизни программиста....
---
k3wl
← →
REA (2005-01-16 12:39) [26]SameValue еще
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.055 c