Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Вниз

Почему так?   Найти похожие ветки 

 
SergP ©   (2004-07-08 23:54) [0]

Почему эти два куска кода работают по разному?

function proverka1(a:byte):boolean;
begin
a:=a-30;
result:=a<5;
end;

function proverka2(a:byte):boolean;
begin
result:=(a-30)<5;
end;


 
Palladin ©   (2004-07-08 23:58) [1]

Это в каком смысле они по разному работают?


 
SergP ©   (2004-07-08 23:59) [2]

Код который генерит компилятор я не смотрел. Лень...
Но интерестно как он считает:
result:=(a-30)<5  ?

Преобразовывает это в
result:=a<35 или при вычислении a-30 использует результат не типа byte ?


 
DeadMeat ©   (2004-07-09 00:00) [3]


> result:=a<35 или при вычислении a-30 использует результат
> не типа byte ?

Скорее всего...

---
...Death Is Only The Begining...


 
SergP ©   (2004-07-09 00:00) [4]


>  [1] Palladin ©   (08.07.04 23:58)
> Это в каком смысле они по разному работают?


при некоторых одинаковых значениях аргумента обе функции выдают разные результаты...


 
YurikGL ©   (2004-07-09 00:02) [5]


> при некоторых одинаковых значениях аргумента обе функции
> выдают разные результаты...

Видимо, при а<30 ?


 
Palladin ©   (2004-07-09 00:06) [6]

я не поленился...
В первом варианте от значения находящегося в стеке отнимается 30 и потом это значение сравнивается... используется сравнение с al
Во втором варианте все приводится к 32 и идет обработка eax...
почему? вопрос к borland...


 
SergP ©   (2004-07-09 00:09) [7]


> Видимо, при а<30 ?


Ага...


 
YurikGL ©   (2004-07-09 00:10) [8]


> SergP ©   (09.07.04 00:09) [7]

Могу попробовать объяснить по простому, в первом случае результат приводится к byte, во втором, - к longint или чему-то подобному.


 
Palladin ©   (2004-07-09 00:11) [9]

А конкретный пример разного результата можно привести?


 
DeadMeat ©   (2004-07-09 00:12) [10]

Если а будет меньше 30... т.е. 29, 28, 27, 26... Кажись так...

---
...Death Is Only The Begining...


 
Anatoly Podgoretsky ©   (2004-07-09 00:14) [11]

Так нельзя использовать, байт это беззнаковое, а при -30 может произойти переполнение.


 
SergP ©   (2004-07-09 00:17) [12]


>  [9] Palladin ©   (09.07.04 00:11)
> А конкретный пример разного результата можно привести?


при a>=35
proverka1=false
proverka2=false

при 30<=a<35
proverka1=true
proverka2=true

При a<30 имеем разные результаты:
proverka1=false
proverka2=true


 
jack128 ©   (2004-07-09 00:17) [13]


> Так нельзя использовать, байт это беззнаковое, а при -30
> может произойти переполнение
оно и при +30 может произойти ;-)


 
Palladin ©   (2004-07-09 00:23) [14]

это очень поучительно, когда работа в стеке идет с одним байтом и когда проводится реальное сравнение... работа с параметр в первом случае как я уже сказал ведется как с байтом (al), соответсвенно 10-30=235 что естественно больше чем 30... во втором случае все справедливо переводится в знаковое integer и сравнение происходит корректно...


 
jack128 ©   (2004-07-09 00:30) [15]


> это очень поучительно,
угу. C {$R+} и {$Q+} - навсегда -)


 
Piter ©   (2004-07-09 00:46) [16]

ну тут уже ответили, но вставлю свои пять копеек...

Это потому что вычисления проводятся как integer, а потом идет приведение типов.

a:=a-30;
result:=a<5;


Допустим, параметр "a=20".
В этом случае "a-30" будет "-10".
Потом идет приведение типов, "-10" приводится к типу Byte (к левой части). В этом случае получается, что "a=246". Ибо "-10", а точнее $F6 в понимании Byte это 246.
А 246 никак не меньше пяти. Значит, будет False.
Правда, при приведении "-10" к Byte будет сгенерировано исключение ERangeError, если включить галочку "Project->Options...->Compiler->Range Checking"

----------------------------------------------------------------------------------------------------

function proverka2(a:byte):boolean;
begin
result:=(a-30)<5;
end;


в этом случае вычисления проводятся тоже как integer. Если "a=20", то "a-30" получается "-10". И далее не идет никакого приведения к Byte, поэтому "-10" сравнивается с "5". Конечно, 5 больше. Поэтому True.
Вот и все различия.
Только заметь, что при включенном "Range Checking" первый вариант будет выдывать исключение, а второй нет. То есть, первый вариант работает "неправильно".
Поэтому отлаживать проект надо при включенных "Range Checking" и "Overflow Checking". А в конечном билде их отключать.

Можно еще вычитать не 30, а допустим 2147483678:

function proverka1(a:byte):boolean;
begin
a:=a-2147483678;
result:=a<5;
end;

function proverka2(a:byte):boolean;
begin
result:=(a-2147483678)<5;
end;


Тогда если даже "a=20" то обе функции будут все равно выдавать False (если отключить проверки на Range и Overflow).

Ибо тогда во втором случае уже будет переполнен integer.
И в понятии integer "20 - 2147483678" будет равно "2147483638" как это не парадоксально :)

А вообще http://www.baseprogram.narod.ru


 
Anatoly Podgoretsky ©   (2004-07-09 01:26) [17]

jack128 ©   (09.07.04 00:17) [13]
Да но у него отключены все проверки и при варианте 1 результат обрезается по модулю 256, а во втором случае нет.



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.031 c
14-1089300094
СатирЪ
2004-07-08 19:21
2004.07.25
Proxies.dcu


1-1089552359
Tahion2
2004-07-11 17:25
2004.07.25
Добавить прозрачную Label на CoolBar без полосы.


14-1089085236
jb
2004-07-06 07:40
2004.07.25
Чего бы плохого шефу сделать


14-1088795176
Vasya.ru
2004-07-02 23:06
2004.07.25
Кто с чего начинает писать программу?


14-1089116491
Акуля
2004-07-06 16:21
2004.07.25
какую книжку лучше почитать





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский