Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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
1-1106230840
Алексей
2005-01-20 17:20
2005.02.06
Работа со строками


3-1105334675
first_aid
2005-01-10 08:24
2005.02.06
Други помогите Interbas совский запрос переделать в Access овский


3-1104746376
Liavik
2005-01-03 12:59
2005.02.06
Locate, Bookmark and BD


14-1105658183
Чеширский_Кот
2005-01-14 02:16
2005.02.06
что такое Cameo?


8-1097810088
jokerxp
2004-10-15 07:14
2005.02.06
микшер Line In





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский