Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.06;
Скачать: CL | DM;

Вниз

Неожиданное открытие?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.071 c
4-1103434952
DelphiN!
2004-12-19 08:42
2005.02.06
Передача параметров потоковой процедуры


10-1082362359
7th_Angel
2004-04-19 12:12
2005.02.06
Диаграммы в Excel


4-1103268331
Progh
2004-12-17 10:25
2005.02.06
Копирование папки


14-1106037527
}|{yk
2005-01-18 11:38
2005.02.06
Линуксоиды!


4-1103099704
Max Ivanych
2004-12-15 11:35
2005.02.06
Как организовать вывод кириллицы в англоязычных Windows?