powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Потеря точности????
46 сообщений из 46, показаны все 2 страниц
Потеря точности????
    #34049631
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть код:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
double x= 0 . 000000001 ,z1;
unsigned long y= 1000000000 ,z2;

z1=x*y;
z2=x*y;
cout<<"x:"<<x<<"\ny:"<<y<<"\n";
cout<<"z1=x*y:"<<z1<<"\nz2=x*y:"<<z2<<"\n";
x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
z2=x*y;
cout<<"x:"<<x<<"\ny:"<<y<<"\n";
cout<<"z1=x*y:"<<z1<<"\nz2=x*y:"<<z2<<"\n";


получим следующие результаты:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
x:1e- 09 
y: 1000000000 
z1=x*y: 1 
z2=x*y: 1 
x: 1 .6e- 06 
y: 625000 
z1=x*y: 1 
z2=x*y: 0 
Явно что во втором случае z2=0 не правильно, но не пойму почему так и почему в первом случае (x и у - степень десяти) все работает как надо...
Any ideas?
...
Рейтинг: 0 / 0
Потеря точности????
    #34049826
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесть нет потери точности, потому как double в принциве неточный тип данных. Ты выведи double в полном формате, чтобы не одна десятичная цифра была, а больше, и увидешь все, что происходит. Так что здесь все правильно.
...
Рейтинг: 0 / 0
Потеря точности????
    #34049920
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЗдесть нет потери точности, потому как double в принциве неточный тип данных. Ты выведи double в полном формате, чтобы не одна десятичная цифра была, а больше, и увидешь все, что происходит. Так что здесь все правильно.

Да неее... тут че-то другое.
1. cout.precision(10) все равно выводит те же числа.
2. если делаем так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
double x,z1;
unsigned long y,z2;

double temp;

x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
temp=x*y;
z2=temp;
cout<<"x:"<<x<<"\ny:"<<y<<"\n";
cout<<"z1=x*y:"<<z1<<"\nz2=x*y:"<<z2<<"\n";
то все работает и мы получаем 1 как для z1 так и для z2!
Т.е. какого-то она странным образом округляет/отбрасывает че-то в случае если тип результирующей переменной unsigned long.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050014
a_shar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В VC 6 все нормально выводит.

x:1e-009
y:1000000000
z1=x*y:1
z2=x*y:1
x:1.6e-006
y:625000
z1=x*y:1
z2=x*y:1
...
Рейтинг: 0 / 0
Потеря точности????
    #34050071
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaill какой компилятор?
...
Рейтинг: 0 / 0
Потеря точности????
    #34050118
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050138
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555
m> т.к. результат должен быть unsigned, компилятор x приводит
m> к unsigned (в резульатае 0), а затем перемножает. Таким
m> образом получаем 0 в результатеЕсли мне не изменяет память, то по стандарту два операнда приводятся к максимальному типу, а к типу результата уже приводится результат операции
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Потеря точности????
    #34050186
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Карабас Барабас man_555
m> т.к. результат должен быть unsigned, компилятор x приводит
m> к unsigned (в резульатае 0), а затем перемножает. Таким
m> образом получаем 0 в результатеЕсли мне не изменяет память, то по стандарту два операнда приводятся к максимальному типу, а к типу результата уже приводится результат операции
Posted via ActualForum NNTP Server 1.3

да, помоему так и есть....

компилятор:
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-56)
...
Рейтинг: 0 / 0
Потеря точности????
    #34050210
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.

Хотя это единственное логичное объяснение
...
Рейтинг: 0 / 0
Потеря точности????
    #34050254
LeonM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В "древних" компиляторах операнды сперва приводились к типу первого из них. Сравните x*y и y*x.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050261
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaill man_555imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.

Хотя это единственное логичное объяснение

Сделай как сказал MasterZiv для двух вариантов. В первом будет 1.000000000, а во втором 0,99999999999
...
Рейтинг: 0 / 0
Потеря точности????
    #34050289
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaill man_555imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.

Хотя это единственное логичное объяснение

а ради эксперимента попробуй
z1=y/x;
z1=x*(double)y;

Интересно, что получится?

Про стандарт: не помню, поэтому буду благодарен, если ткнёте носом в нужный абзац.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050305
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh bemtaill man_555imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.

Хотя это единственное логичное объяснение

Сделай как сказал MasterZiv для двух вариантов. В первом будет 1.000000000, а во втором 0,99999999999

Подожди, не понял:)
MasterZiv сказал:
"Ты выведи double в полном формате, чтобы не одна десятичная цифра была, а больше, и увидешь все, что происходит. Так что здесь все правильно."
Ну я и вывожу по десять знаков после запятой. Для обоих вариантов.
+
почему тогда в таком случае работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
double x,z1;
unsigned long y,z2;

double temp;

x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
temp=x*y;
z2=temp;
cout<<"x:"<<x<<"\ny:"<<y<<"\n";
cout<<"z1=x*y:"<<z1<<"\nz2=x*y:"<<z2<<"\n";
ведь согласно твоему предположению temp=0,99999999 (хотя реально он равен 1) и при присваивании z2=temp ничего не теряется...

Такое ощущение что компилятор глючит...
...
Рейтинг: 0 / 0
Потеря точности????
    #34050315
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeonMВ "древних" компиляторах операнды сперва приводились к типу первого из них. Сравните x*y и y*x.

компилятор не глючит ;-)
...
Рейтинг: 0 / 0
Потеря точности????
    #34050318
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555 bemtaill man_555imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.

Хотя это единственное логичное объяснение

а ради эксперимента попробуй
z1=y/x;
z1=x*(double)y;

Интересно, что получится?

Про стандарт: не помню, поэтому буду благодарен, если ткнёте носом в нужный абзац.

Ща попробую...
...
Рейтинг: 0 / 0
Потеря точности????
    #34050360
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaillведь согласно твоему предположению temp=0,99999999 (хотя реально он равен 1) и при присваивании z2=temp ничего не теряется...

Такое ощущение что компилятор глючит...

Ты уверен, что при выводе в stdout дубль не округляется?
...
Рейтинг: 0 / 0
Потеря точности????
    #34050376
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh bemtaillведь согласно твоему предположению temp=0,99999999 (хотя реально он равен 1) и при присваивании z2=temp ничего не теряется...

Такое ощущение что компилятор глючит...

Ты уверен, что при выводе в stdout дубль не округляется?

Еще больше не понял:)

Это че получается, говоришь вывести дубль а выводит автоматом инт???
ща тогда в дебагере посмотрю...
...
Рейтинг: 0 / 0
Потеря точности????
    #34050391
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaillща тогда в дебагере посмотрю...

Вот отсюда и стоит разбиратья
...
Рейтинг: 0 / 0
Потеря точности????
    #34050415
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555 bemtaill man_555imho происходит это потому, что
y - unsigned
z2 - unsigned

т.к. результат должен быть unsigned, компилятор x приводит к unsigned (в резульатае 0), а затем перемножает. Таким образом получаем 0 в результате.

Хотя это единственное логичное объяснение

а ради эксперимента попробуй
z1=y/x;
z1=x*(double)y;

Интересно, что получится?

Про стандарт: не помню, поэтому буду благодарен, если ткнёте носом в нужный абзац.


Прикольно:
Код: plaintext
1.
2.
3.
4.
5.
z1=y/x: 390625000000 
z1=x*(double)y: 1 
 
z2=y/x: 4077943360 
z2=x*(double)y: 0 

z1 - double
z2 - unsigned int

очевидно переполнение UInt
...
Рейтинг: 0 / 0
Потеря точности????
    #34050431
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh bemtaillща тогда в дебагере посмотрю...

Вот отсюда и стоит разбиратья

короче ни че ни где не округлетя - все как на экране так и в дебагере!
...
Рейтинг: 0 / 0
Потеря точности????
    #34050443
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лана надо работать, а то уже 2 часа на эту хрень убил:)) если у кого какие мысле появятся - пишите, буду рад!
...
Рейтинг: 0 / 0
Потеря точности????
    #34050455
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лана надо работать, а то уже 2 часа на эту хрень убил:)) если у кого какие мысле появятся - пишите, буду рад!
...
Рейтинг: 0 / 0
Потеря точности????
    #34050497
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотите объясню, откуда разница между этим
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
double x,z1;
unsigned long y,z2;
double temp;
x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
temp=x*y;
z2=temp;
и этим
Код: plaintext
1.
2.
3.
4.
5.
6.
double x,z1;
unsigned long y,z2;
x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
z2=x*y;
По-хорошему, надо на генерируемый код смотреть, но так навскидку...
Вы же на x86 тестируете, да :) ?
Компилятор приводит x и y к double (естественно), перемножает, в результате получается что-то типа 0.9(9 в периоде). В регистре сопроцессора - то есть десятибайтный тип. Теперь если сразу приводить к long, компилятор делает это прямо из этого регистра сопроцесссора, а там целая часть 0. А если сначала сохранить в переменную double - а это восьмибайтный тип - то произойдет округление к ближайшему числу представимому в double, а это как раз 1. С msvc результаты одинаковые, так как он устанавливает для сопроцессора режим вычислений с восьмибайтной точностью.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050504
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати если заменить double temp на long double temp (а это десятибайтный тип в gcc и bcc) то снова будет 0.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050522
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneХотите объясню, откуда разница между этим
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
double x,z1;
unsigned long y,z2;
double temp;
x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
temp=x*y;
z2=temp;
и этим
Код: plaintext
1.
2.
3.
4.
5.
6.
double x,z1;
unsigned long y,z2;
x= 0 . 0000016 ;
y= 625000 ;
z1=x*y;
z2=x*y;
По-хорошему, надо на генерируемый код смотреть, но так навскидку...
Вы же на x86 тестируете, да :) ?
Компилятор приводит x и y к double (естественно), перемножает, в результате получается что-то типа 0.9(9 в периоде). В регистре сопроцессора - то есть десятибайтный тип. Теперь если сразу приводить к long, компилятор делает это прямо из этого регистра сопроцесссора, а там целая часть 0. А если сначала сохранить в переменную double - а это восьмибайтный тип - то произойдет округление к ближайшему числу представимому в double, а это как раз 1. С msvc результаты одинаковые, так как он устанавливает для сопроцессора режим вычислений с восьмибайтной точностью.

Действительно!!! Спасибо.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050611
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone а Вы уверены, что именно 0.0000016 не представляется точно в формате с плавающей точкой? Как и 0.0000032, 0.0000048, 0.0000064, и т.д.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050627
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555 Barlone а Вы уверены, что именно 0.0000016 не представляется точно в формате с плавающей точкой? Как и 0.0000032, 0.0000048, 0.0000064, и т.д.

Вообще-то. Даже 1.0 не является точным.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050690
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhВообще-то. Даже 1.0 не является точнымединица - это любое основание системы в степени 0, где неточность ?
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Потеря точности????
    #34050691
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, ну 1 то можно представить точно. Проблема в том что результат вычислений не равен этому точному представлению. А 0.0000016 (=1/625000) конечно не может быть представлено точно. Точно можно представить только числа представимые в виде дроби со степенью 2 в знаменателе.
...
Рейтинг: 0 / 0
Потеря точности????
    #34050821
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Карабас Барабас AkhВообще-то. Даже 1.0 не является точнымединица - это любое основание системы в степени 0, где неточность ?
Posted via ActualForum NNTP Server 1.3

Колличество значимых бит не хватает, чтобы быть уверенным, что число представленное в дубле как 1.0, являестя единицей
...
Рейтинг: 0 / 0
Потеря точности????
    #34050831
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh A> Колличество значимых бит не хватает, чтобы быть уверенным,
A> что число представленное в дубле как 1.0, являестя
A> единицейсначала ты говорил про число один (1.0), а теперь про предятавление :)
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Потеря точности????
    #34050872
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Карабас Барабас Akh A> Колличество значимых бит не хватает, чтобы быть уверенным,
A> что число представленное в дубле как 1.0, являестя
A> единицейсначала ты говорил про число один (1.0), а теперь про предятавление :)

Это я man_555 отвечал. :)
...
Рейтинг: 0 / 0
Потеря точности????
    #34051022
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если 1 не точно предсталяется, то по логике тогда, умножив 1 на 1 n раз, я должен получить число более близкое к 0, чем к 1. Правильно?
...
Рейтинг: 0 / 0
Потеря точности????
    #34051058
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555если 1 не точно предсталяется, то по логике тогда, умножив 1 на 1 n раз, я должен получить число более близкое к 0, чем к 1. Правильно?

Почему с разу к 0-лю, может к бесконечности?
...
Рейтинг: 0 / 0
Потеря точности????
    #34051102
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhПочему с разу к 0-лю, может к бесконечности?

вообще-то к 0-лю.

0,99 * 0,99 = 0,9801
...
Рейтинг: 0 / 0
Потеря точности????
    #34051152
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555 AkhПочему с разу к 0-лю, может к бесконечности?

вообще-то к 0-лю.

0,99 * 0,99 = 0,9801

Почему это не точное число обязательно должно восприниматься в меньшую сторону?
0.999999999999999999999999999999999999(7)=1.000000000000000000000000000000
1.000000000000000000000000000000000000(2)=1.000000000000000000000000000000
1.000000000000000000000000000000000000(5)=1.000000000000000000000000000001
В скобках, то что выпало за разряды точности.
...
Рейтинг: 0 / 0
Потеря точности????
    #34051234
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh
Почему это не точное число обязательно должно восприниматься в меньшую сторону?
0.999999999999999999999999999999999999(7)=1.000000000000000000000000000000
1.000000000000000000000000000000000000(2)=1.000000000000000000000000000000
1.000000000000000000000000000000000000(5)=1.000000000000000000000000000001
В скобках, то что выпало за разряды точности.

конечно необязательно - хоть в большую. Только 1 сколько не умножай на себя всегда будет 1 в представлении float
...
Рейтинг: 0 / 0
Потеря точности????
    #34051270
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555Только 1 сколько не умножай на себя всегда будет 1 в представлении float

Очень хорошо. Но не надо говорить о точном представлении чисел в форматах с плавающей точкой.
...
Рейтинг: 0 / 0
Потеря точности????
    #34051291
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhОчень хорошо. Но не надо говорить о точном представлении чисел в форматах с плавающей точкой.

Чего-то не понял.. а разве нельзя некоторые числа во флоуте точно представить? 1, 44.53 например?
...
Рейтинг: 0 / 0
Потеря точности????
    #34051359
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555 AkhОчень хорошо. Но не надо говорить о точном представлении чисел в форматах с плавающей точкой.

Чего-то не понял.. а разве нельзя некоторые числа во флоуте точно представить? 1, 44.53 например?

Для операций с плавающей точкой существует понятие количество значимых разрядов (определяется длиной мантиссы), которое учитывается для выбора типа представления данных. Результирующее число, которое находится в переменной вещественного типа, соответственно, тоже имеет определенное количество значимых разрядов, но оно обычно меньше, чем типа, ибо, над числами выполняются арефметические операции, которые неуклонно увеличивают погрешность. Максимальная точность числа в вещественном типе = точности типа.
Так воспринимают и работают с числами с плавающией точкой.
А точно число представляется, .... точно число представляется в int, long , ... . ;)
...
Рейтинг: 0 / 0
Потеря точности????
    #34051417
man_555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот оно как! а как это проверить на практике? убедиться собственными глазами?
...
Рейтинг: 0 / 0
Потеря точности????
    #34051514
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и кто выиграл ? :)
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Потеря точности????
    #34051526
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
man_555вот оно как! а как это проверить на практике? убедиться собственными глазами?

Клади числа в дубль, да умножай их
...
Рейтинг: 0 / 0
Потеря точности????
    #34051552
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Карабас БарабасНу и кто выиграл ? :)

А с полки пирожок будет?
...
Рейтинг: 0 / 0
Потеря точности????
    #34052680
Апять шняга разводится :Тынц
...
Рейтинг: 0 / 0
Потеря точности????
    #34052722
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЯдренБатонАпять шняга разводится :Тынц

И не говори. :)
...
Рейтинг: 0 / 0
46 сообщений из 46, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Потеря точности????
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]