143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
1

Арифметические правила (точность вычисления)

13.02.2016, 18:39. Показов 613. Ответов 6
Метки нет (Все метки)

Нужно было вычислить кол-во пикселей, соответствующее 130 мм.
Сделал формулу:
C++
1
2
int fCp = 1754, fCm = 297. //Размер картинки 1754 пикселя, что соотв. 297мм у принтера
int fRes = (double) fCp / fCm * 130.
Поидее, поставил (double), значит выражение должно считаться с точностью double, и потом результат округлять до int. Но нет, деление сразу округляло до int, и результат был 650, а должен был быть 767(на калькуляторе посчитал).

Задачу то я решил, тупо поменял местами деление с умножением, и естественно результат стал нужным, но сам факт того что (double) не сработал заставил задуматься..

Почему так получилось? И где по подробнее почитать про арифметическую точность?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.02.2016, 18:39
Ответы с готовыми решениями:

Точность вычисления
Вопрос довольно простой. Как сделать так чтобы #include <iostream> #include <iomanip> using...

Точность вычисления определенного интеграла
Не могу понять почему при установке точности вычисления t=1/1000 после запятой в ответе совпадают 2...

арифметические вычисления.уравнение
Подправьте пожалуйста код чтото я накосячил уравнение а*х*х+b=0 a b вводятся с клавиатуры ...

Правила вычисления операндов при использовании cout для вывода нескольких выражений
элементы массива 1 и 2. cout << Y.PopHead() << endl; cout << Y.PopHead() << endl; выводит 1 2...

6
16094 / 8692 / 2124
Регистрация: 30.01.2014
Сообщений: 14,984
13.02.2016, 20:20 2
Цитата Сообщение от Izual Посмотреть сообщение
Сделал формулу
Эта формула вычисляет 767.

Может быть у тебя вот так было написано:
C++
1
2
int fCp = 1754, fCm = 297.; //Размер картинки 1754 пикселя, что соотв. 297мм у принтера
int fRes = fCp / fCm * 130.;
тогда действительно получается 650.
650 получается из-за того, что деление - целочисленное. В С++ целочисленное деление осуществляется тогда, когда оба операнда операции деления - целочисленные. Чтобы этого избежать, достаточно сделать один из операндов вещественным. Что, собственно, в твоей формуле и было сделано посредством приведения типа.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
13.02.2016, 21:41  [ТС] 3
Цитата Сообщение от DrOffset Посмотреть сообщение
Эта формула вычисляет 767.
Да действительно. Было по другому, изначально было так:

C++
1
fErr[4] = (double)(Bitmap.bmHeight/gImN[2])*130.0;
Перепроверил, без скобок результат 650, а с скобками 767.. Т.е. странно, поидее значит синтаксис привидения типа должен быть с скобками общими? Т.е. типа правильный стиль:

C++
1
fErr[4] = (double)((Bitmap.bmHeight/gImN[2])*130.0);
Просто получается, что если ты вдруг скобки поставиш, то результат будет уже другой, т.е. например ситуация:

C++
1
fErr[4] = (double)(Bitmap.bmHeight+gImN[2])*130.0;
Тут скобка эта означает первое действие (я и разсчитывал так в начальном варианте, хотя их ставить было не обязательно, но тут дело даже не в том что обязательно или нет, а в том что это выглядит правильно, т.е. на вид ты можеш определить точно порядок действия, а не полагаться на саму студию т.е. в каком порядке она будет вычислять)

Добавлено через 2 минуты
Хах, лол эти 2 варианта тоже не правильно считают:
C++
1
fErr[4] = (double)((Bitmap.bmHeight/gImN[2])*130.0);
C++
1
fErr[4] = (double)(Bitmap.bmHeight/gImN[2]*130.0);
Результат получается 650 в обоих случаях, без скобок же всё ок.. ~ ~ Теперь я совсем запутался, с какого перепуга то..
0
16094 / 8692 / 2124
Регистрация: 30.01.2014
Сообщений: 14,984
13.02.2016, 21:49 4
Izual, еще раз, определять тип результата можно по типам операндов при делении.
C++
1
2
3
4
5
6
7
8
9
10
11
12
int a = ...;
int b = ...;
 
a / b; // результат - int (деление целочисленное)
 
(double)a / b; // результат - double
 
a / (double)b; // результат - double
 
(double)a / (double)b; // результат - double
 
(double)(a / b); // результат - int, приведенный к double (деление целочисленное)
Вот демонстрация на реальных значениях:
http://rextester.com/MCMT16171
1
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
13.02.2016, 22:08  [ТС] 5
Цитата Сообщение от DrOffset Посмотреть сообщение
по типам операндов при делении.
И что же, если я вдруг захочу поставить скобки, то мне придётся после каждом открытии скобки писать (double)? Мде, я то думал, что если в начале поставить, то вся формула будет вычисляться с точностью double..

Честно говоря - редкая тупость, что так сделано криво в плане синтаксиса, значит общего приведения типа не может быть вообще (для 3+ аргументов), т.е. при каждой новой операции в одной строке формулы, придётся всегда писать (double) ~ ~ Пойду выпью яду чтоль, а то я себе представил формулу из 6 аргументов, где нужно писать 3 раза "(double)", и это всего 6 аргументов, бывает и больше, намного..
0
16094 / 8692 / 2124
Регистрация: 30.01.2014
Сообщений: 14,984
13.02.2016, 22:19 6
Цитата Сообщение от Izual Посмотреть сообщение
значит общего приведения типа не может быть вообще (для 3+ аргументов)
Это "общее приведение" делает приведение для результата выражения.

Цитата Сообщение от Izual Посмотреть сообщение
Пойду выпью яду чтоль, а то я себе представил формулу из 6 аргументов
* Можно сразу пользоваться переменными double, если они постоянно нужны.
* Не обязательно кастить все аргументы, достаточно одного, который вычисляется первым. Если остальные операции зависят от его результата (который будет double), то дальнейшие вычисления тоже будут в double уже без кастов.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
13.02.2016, 23:12  [ТС] 7
Не в обиду*
Цитата Сообщение от DrOffset Посмотреть сообщение
сразу пользоваться переменными double
Тупой вариант, у меня числа в операции - целые, и они точно соответствуют целым числам, и они 4 байтовые! Мне не нужны 8 байтовый даблы, или 4 флоат, которые просто закорруптят значение, бывает в функцию надо int значение передать, и тут бац, я юзаю double или float, теперь вечно буду привязан к 2 проблемам - плавающие числа не точно отображают целочисленную часть, а при приведении, так вообще могут стянуть на +1 или -1 значение, и вторая - даже если всё ок, то тогда если я буду использовать эти переменные в других мат. операциях, где нужны int, то тут я опять попаду с проблемой приведения, как в случае с неправильным округлением, так и вечно писать (int) - имеется ввиду там где нужен int.

Цитата Сообщение от DrOffset Посмотреть сообщение
дальнейшие вычисления тоже будут в double
Ну я понял о чём ты, но это придётся контролировать всё, т.е. потенциально, придётся перепроверять каждую математическую операцию, т.к. хрен знает, будет ли зависить или нет, например:

C++
1
int fn = (double) 10/3 + 15/4
Естественно, после плюса - операции будут int вычисляться.

ПРОСТО БРЕД. Вот так вот и сходят с ума.

Навеяло.. Недавно тут обсуждал тему того как в мире всё глупо устроено:
1 случай - Ночью светофор не горит, я дошол до половины дороги, с переди(в смысле с права) идут машины, стою жду на ограничительной полосе и смотрю на право, проходит последняя машина, я делаю шаг в перёд, поварачиваю голову в перёд и вижу боковым зрением как с лева по разганичивающей полосе летит мед. машина наверно под 100км\ч, без звука сирены, если бы я этот шаг в тот момент не сделал, был бы уже трупом. (реально со мной произошло, я просто ошеломлен был после этого, итог умозаключения - они спасают человека в мед. машине, но по дороге убивают ещё 10-ых.. ну не бред ли?)
2 случай -Обще известный факт о запрете курения в общ. местах, а почему его приняли то? - Потому что ТУПОГОЛОВЫЕ олени, стоят в толпе и курят сигарету, ну не кретины ли?.. Ну отойди в сторону и кури, зачем же дымить на других людей.. Иногда думаеш, да если по дороге ребёнка видиш, то автоматически сигарету прячеш от его взора, как и бутылку с пивом, просто чтоб не нести пропаганду, как пример дурного образа жизни, а тут ситуация, когда люди не понимают что дымят на других.. В результате приняли закон, ну и результат закона - естественно тоже тупорогий, т.к. тут и отмыв денег начался и спекуляция на законе.

Мде.. пора пить не пиво, а реально яд, ибо гнилой мир совсем, и некому наказать этих дигениратов... (щя я за грубость получу бан ^^ извините, но реально точно такой же тупой случай в программировании, что нет общего приведения типа для всей формулы)

Добавлено через 28 минут
Навеяло то что хотелось сказать про тех кто так вот делает: "Выйдем и выслушаем" (камеди, выпуск "газовые переговоры") ^^
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.02.2016, 23:12
Помогаю со студенческими работами здесь

Точность вычисления
Вроде очень банальная проблема, но никак не могу понять, что сделать procedure...

Точность вычисления
Дана программа. x = 0.0: 0.0001: 2.0; y = (x.*atan(x))./(sqrt(1+x.^2)); z = trapz(x,y) Это...

Как увеличить точность вычисления
Всем добрый день) Как увеличить точность вычисления? к примеру матлаб считает что I=...

Точность вычисления переменной double
Здравствуйте, В довольно навороченном приложении такие определения class Class01 { public...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru