Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.84/37: Рейтинг темы: голосов - 37, средняя оценка - 4.84
4 / 4 / 0
Регистрация: 25.06.2010
Сообщений: 106

непонятки

02.08.2011, 13:40. Показов 8701. Ответов 81

Студворк — интернет-сервис помощи студентам
у меня есть прога которая берет дабл и разделяет его на две сост. целое и дробное
C++
1
2
this->z = int(d);
this->p = ( d - int(d) )*100+0.5;
объясните почему без "+0.5" ничего не работает для чисел чья дробная часть( нечетная и меньше равна 9 )?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.08.2011, 13:40
Ответы с готовыми решениями:

непонятки с for
Издавна мучает вопрос почему некоторые используют в цикле for ( int i = n; i < m ; i++), а другая часть населения for ( int i = n; i <...

непонятки с Си
вобщем вот что задали Вот что я зделал при выполнении пишет s=none(или nane-как то так)/почему так?где ошибка? у кого то так же...

Непонятки с WXDev C++
Народ, у кого данный компилятор, помогите разобраться. Вот программа: #include <iostream.h> #include <conio.h> void...

81
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2011, 22:36
Студворк — интернет-сервис помощи студентам
Просто констатация фактов
Миниатюры
непонятки  
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
02.08.2011, 23:23
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- если модуль val будет превосходить INT_MAX не будет потери точности вычислений?
Конечно будет. Замените int на int64_t, чтобы ни о чём плохом не думать... Задача-то, на сколько я понял, выдать по отдельности целыми числами целую и дробную части. У меня как-раз это и происходит (при учёте, что и та и другая помещаются в INT_MAX (INT_MIN)), а у Вас?
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
02.08.2011, 23:51
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Ну просто зачем ещё 0,5 добавлять, почти во всех постах оно сквозит, достаточно добавить 10^-5 чтобы преобразование int() было корректным
Беда-то в том, что я смогу ответить на вопрос почему именно 0.5, а вот сможешь ли ты убедительно ответить почему именно 10^-5? Почему не 0.001 или 0.000001? Ответ "потому что и так работает" выглядит слабо.
Кстати, pow(0.1,4) это не 10^-5
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.08.2011, 00:18
grizlik78,
Цитата Сообщение от grizlik78 Посмотреть сообщение
почему именно 0.5
?
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.08.2011, 00:36
Потому, что это верхняя граница абсолютного значения ошибки представления целого числа, которую ещё можно исправить. И способ её исправления — округление до ближайшего целого.
То есть если известно, что число должно быть целым, то если истинная ошибка по модулю меньше 0.5, то достаточно просто округлить к ближайшему целому. Если ошибка больше, то её не исправить.
Алгоритм округления я показывал в функции:
Если число положительное, то надо добавить 0.5 и округлить к минус бесконечности (floor).
Если число отрицательное, то надо вычесть 0.5 и округлить к плюс бесконечности (ceil).
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.08.2011, 00:42
Цитата Сообщение от grizlik78 Посмотреть сообщение
Потому, что это верхняя граница абсолютного значения ошибки представления целого числа, которую ещё можно исправить.
Это сверх моего понимания...

Цитата Сообщение от grizlik78 Посмотреть сообщение
И способ её исправления — округление до ближайшего целого.
В какую сторону?

Цитата Сообщение от grizlik78 Посмотреть сообщение
То есть если известно, что число должно быть целым, то если истинная ошибка по модулю меньше 0.5, то достаточно просто округлить к ближайшему целому.
Это опять сверх моего понимания... (ключевые слова выделены)
0
03.08.2011, 00:42

Не по теме:

Цитата Сообщение от grizlik78 Посмотреть сообщение
Если число отрицательное...
Вот об этом я как-то не задумался, спасибо!

0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.08.2011, 01:00
Цитата Сообщение от lazybiz Посмотреть сообщение
В какую сторону?
Для тех, кто на бронепоезде
До ближайшего целого. Этому в школе учат.
23.71 округляется до 24,
23.1 округляется до 23
23.5 округляется до 24
23.499 округляется до 23
-17.6 округляется до -18
-17.3 округляется до -17
-17.5 округляется до -18
-17.49 округляется до -17
Это называется до ближайшего целого.

Добавлено через 13 минут
Цитата Сообщение от lazybiz Посмотреть сообщение
Это сверх моего понимания...
Согласен, предложение сложное. Так бывает.
Дробные числа хранятся в памяти в усечённом виде, так как нет способа представить абсолютно любую дробь конечным количеством битов. Поэтому после умножения, к примеру, 0.11 на 100 мы получим не точно 11, а число близкое к 11, с некоторой ошибкой. Это не вызывает несогласия?
Ошибка может быть как положительной, так и отрицательной.
Кроме того, поскольку 0.11 получается у нас в результате вычитания (когда целую часть отнимаем), то ошибка эта может быть довольно существенной. В общем случае чем больше по модулю целая часть, тем больше будет модуль возможной ошибки.
В результате вместо 11 у нас может получится, к примеру, 11.07 или может 10.95, или ещё какое. Конечно, для получения настолько большой ошибки разрядности int в 32 бита не хватит, но можно ведь и более вместительный тип взять.
Так вот, пока модуль ошибки меньше чем 0.5, эту ошибку можно полностью устранить. Округлением до ближайшего целого.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.08.2011, 01:16
Так
Цитата Сообщение от lazybiz Посмотреть сообщение
почему именно 0.5
?
Я так и не понял. И думаю не я один...

Цитата Сообщение от grizlik78 Посмотреть сообщение
Потому, что это верхняя граница абсолютного значения ошибки представления целого числа, которую ещё можно исправить.
Давай простыми словами.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
03.08.2011, 01:17
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* ANSI C 99 */
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
 
#define signround(d) ( ( (d) < 0.0 ) ? ceil((d) - 0.5) : floor((d) + 0.5) )
#define PRECISION 3
 
int64_t lost_tail_zeros(int64_t num){
    while ( num && ! ( num % 10ll ) )
        num /= 10ll;
    return num;
}
 
int main(void){
    double val;
    
    while ( printf("> ") && scanf("%lf", &val) == 1 ){
        double tmp = signround(val * pow(10.0, PRECISION));
        int64_t iPart = (int64_t)(tmp / pow(10.0, PRECISION));
        int64_t fPart = lost_tail_zeros((int64_t)tmp % (int64_t)(pow(10.0, PRECISION)));
        printf("Int part: %lld  Fract part: %lld\n", iPart, fPart);
    }
    
    exit(0);
}
0
03.08.2011, 01:18

Не по теме:

Цитата Сообщение от lazybiz Посмотреть сообщение
Давай простыми словами.
А смысл? Помолчу-ка я дальше.

0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.08.2011, 01:19
Цитата Сообщение от grizlik78 Посмотреть сообщение
А смысл? Помолчу-ка я дальше.
Это будет правильно с твоей стороны.
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.08.2011, 01:20
easybudda, а зачем правые нули удаляешь? Они же значащие при заданной разрядности.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
03.08.2011, 01:30
Цитата Сообщение от grizlik78 Посмотреть сообщение
easybudda, а зачем правые нули удаляешь?
Да чёрт его знает. Мне так красивше показалось, когда 3.05 раскладывается на 3 и 5, а не на 3 и 50. Может оно и не правильно...
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.08.2011, 01:32
Красивше, да
Но семантика-то у них 3 целых и 50 тысячных. Про то что 50 тысячных стали 5-ю сотыми из вывода уже не понять.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
03.08.2011, 09:11
Цитата Сообщение от grizlik78 Посмотреть сообщение
Беда-то в том, что я смогу ответить на вопрос почему именно 0.5, а вот сможешь ли ты убедительно ответить почему именно 10^-5? Почему не 0.001 или 0.000001? Ответ "потому что и так работает" выглядит слабо.
Кстати, pow(0.1,4) это не 10^-5
А теперь внимание сюрприз
C++
1
2
3
fpart = floor(val);
        spart = val - fpart;
        cout<<fpart<<" RU "<<int(100.0*spart + pow(10,-12))<<" KOP\r\n";
Скомпилируй и посмотри что и при pow(10,-12) успешно работает, я же говорил что 2,0 будет представляться как 1,9(9), ну да ладно, я к другому - если ты слышал о погрешности то добавляя 0,5 ты вносишь значительную погрешность, а для числа скажем 0,01 вносишь возмущение 5000% - и заявляешь о точности!

Далее
Цитата Сообщение от easybudda Посмотреть сообщение
int64_t iPart = (int64_t)(tmp / pow(10.0, PRECISION));
int64 9223372036854775807
double 1.79769e+308


Рассмотрим случай - я програмно ввёл целую часть 9223372036854775890 - и что тогда???
А если введу только целую часть 1.79769e+308, к какому тогда типу приводить будешь???Я пытался тебе показать что если есть тип данных с максимальным диапазоном, то не следует его целую часть преобразовывать к типу с меньшей разрядностью.
Дробная часть у меня в алгоритме изначально правильно выводилась, так что не нужно приделывать пару дополнительных колёс к коду - эту запись
C++
1
int(100.0*spart + pow(10,-12))
вводил только для копеек.
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.08.2011, 11:23
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Скомпилируй и посмотри что и при pow(10,-12) успешно работает
Да пожалуйста. Первая строчка вывода твоя, вторая моя.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <cmath>
 
int main()
{
    double val = 30000.12;
    int fpart;
    double spart;
 
    fpart = floor(val);
    spart = val - fpart;
    std::cout<<fpart<<" RU "<<int(100.0*spart + pow(10,-12))<<" KOP\r\n";
    std::cout<<fpart<<" RU "<<int(100.0*spart + 0.5)<<" KOP\r\n";
    return 0;
}
Вывод для числа 30000.12:
30000 RU 11 KOP
30000 RU 12 KOP

Вот уж сюрприз сюрпризов, ага.
Так почему 10^-12 или 10^-5 или сколько надо-то?

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
а для числа скажем 0,01 вносишь возмущение 5000% - и заявляешь о точности!
Обидно, я столько написал, а оказывается впустую. Ладно хоть не на бумаге.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Рассмотрим случай - я програмно ввёл целую часть 9223372036854775890 - и что тогда???
Возможно для тебя и это будет сюрпризом, но double не способен сохранить точно такое целое число. То есть здесь ошибка будет уже не копейками исчисляться, а сотнями рублей.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
А если введу только целую часть 1.79769e+308, к какому тогда типу приводить будешь???
Ежели очень хочется, то можно длинное целое из MPL взять. Только смысла нет. Здесь ошибка будет такая, сколько денег на земле никогда не было и не будет

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Я пытался тебе показать что если есть тип данных с максимальным диапазоном, то не следует его целую часть преобразовывать к типу с меньшей разрядностью.
И здесь беда, так как для точного представления целых чисел int64_t является более вместительным, чем double.
1
paladin
 Аватар для Yurii_74
286 / 187 / 7
Регистрация: 25.02.2009
Сообщений: 589
03.08.2011, 12:43
Мда... тяжёлый тут случай. Лучше займитесь чем-нибудь более полезным (например, класс напишите для хранения сколь угодно большого целого числа, влезающего в оперативку, затем на его основе класс рациональных чисел можно забабахать).

Если по теме, то погрешность у целых чисел наподобие int абсолютная (+/-0,5), а у вещественных (флоуты, даблы там всякие) - относительная (какие-то части процента). Это на предмете Архитектура ЭВМ должны вдалбливать, но многие интересующиеся/способные узнают эту инфу много раньше.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
03.08.2011, 12:51
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Рассмотрим случай - я програмно ввёл целую часть 9223372036854775890 - и что тогда???
Ну до фанатизма-то доходить не нужно. Ещё раз повторяю - цель была представить целыми числами целую и дробную части, а не просто вывести на экран, при чём с сомнительной точностью. Если речь о таких больших числах - длинная арифметика в помощь. Но только здесь явно другое было нужно.

Не по теме:

Цитата Сообщение от grizlik78 Посмотреть сообщение
сколько денег на земле никогда не было и не будет
Если в монгольские тугрики пересчитать, то и long double не хватит... ;)

0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
03.08.2011, 13:14
Цитата Сообщение от grizlik78 Посмотреть сообщение
Вот уж сюрприз сюрпризов, ага.
Вбей вот так и давай забудем эту тему
C++
1
2
3
4
5
6
fpart = floor(val);
        spart = val - fpart;
        cout<<fpart<<" RU "<<100.0*spart<<" KOP\r\n";
 
        cout<<"Celay chast'"<<fpart<<"\r\n";
        cout<<"Drobn chast'"<<spart<<"\r\n";
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.08.2011, 13:14

Непонятки с итераторами
Здравствуйте, господа программисты. Пытался написать вот эту задачку, но получается что-то нехорошее. Помогите, пожалуйста! #include...

Непонятки со списком
Нашёл код в интернете и немного не понимаю его в некоторых местах. Объясните мне пожалуйста, зачем в коде вот тут: ...

Непонятки с выводом
Задание гласит: Вычислить приближенное значение конечной суммы с точностью e:0.0005 ...

Непонятки с сортировкой
Добрый вечер. Практически выполнил задание, но в конце возникла проблема с сортировкой, а именно, в задании нужно ввести название товара,...

Непонятки со scanf
char str_check; //строка для функции &quot;check&quot;, которая проверяет введенные данные { scanf(&quot;%s&quot;,&amp;str_check); } ...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла: Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Новости компьютерного мира и их обсуждение (4) Салют, шампанское, овации! :drink:
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru