Форум программистов, компьютерный форум CyberForum.ru

непонятки - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 37, средняя оценка - 4.65
Noname2512
4 / 4 / 1
Регистрация: 25.06.2010
Сообщений: 106
02.08.2011, 13:40     непонятки #1
у меня есть прога которая берет дабл и разделяет его на две сост. целое и дробное
C++
1
2
this->z = int(d);
this->p = ( d - int(d) )*100+0.5;
объясните почему без "+0.5" ничего не работает для чисел чья дробная часть( нечетная и меньше равна 9 )?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
grizlik78
Эксперт С++
 Аватар для grizlik78
1887 / 1419 / 103
Регистрация: 29.05.2011
Сообщений: 2,967
03.08.2011, 13:17     непонятки #61
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Вбей вот так и давай забудем эту тему
Не смешно. Здесь нет целого, а округление производит cout.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9382 / 5432 / 916
Регистрация: 25.07.2009
Сообщений: 10,428
03.08.2011, 13:57     непонятки #62
Цитата Сообщение от grizlik78 Посмотреть сообщение
округление производит cout
Кстати, тоже вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <iomanip>
#include <sstream>
 
int main(){
    double d;
    
    while ( std::cout << "> " && std::cin >> d ){
        std::stringstream ss;
        int iPart, fPart;
        char ch;
        
        ss << std::fixed << std::setprecision(3) << d;
        ss >> iPart >> ch >> fPart;
        
        std::cout << "Int part: " << iPart << " Fract part: " << fPart << std::endl;
    }
    
    return 0;
}
grizlik78
03.08.2011, 13:59
  #63

Не по теме:

Чего только люде не сделают, чтобы 0.5 не прибавлять

-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 14:21     непонятки #64
Цитата Сообщение от grizlik78 Посмотреть сообщение

Не по теме:

Чего только люде не сделают, чтобы 0.5 не прибавлять

Напишу грубо т.к. устал от препинаний здесь, я не виноват что кто-то ТУГОЙ и за сout совсем с другой целью писал, вобщем ничего не прибавляю, не убавляю, вот тебе пример и тестируй на здоровье
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
29
30
//http://www.cyberforum.ru/cpp-beginners/thread338338.html
#include <stdio.h>
#include <conio.h>
#include <math.h>
 
int main()
{
    char ch;
    double val;
 
    double fpart;
    double spart;
    do
    {
        printf("Enter double\r\n");
        scanf("%lf",&val);
 
        fpart = floor(val);
        spart = val - fpart;
        printf("%.0f RU %.0f KOP\r\n",fpart,100.0*spart);
 
        printf("Celay chast' %lf\r\n",fpart);
        printf("Drobn chast' %lf\r\n",spart);
 
        printf("[Y/N] - Y - Enter new value\r\n");
        ch = getch();
    }
    while(ch == 'Y' || ch == 'y');
    return 0;
}
Миниатюры
непонятки  
grizlik78
03.08.2011, 15:05
  #65

Не по теме:

Кто-то, ага. Теперь printf делает округление, что замечательно видно на скриншотах.
-=ЮрА=-, надеюсь ты не работаешь программистом, и не собираешься (я не работаю).

-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 16:02     непонятки #66
Цитата Сообщение от grizlik78 Посмотреть сообщение
Теперь printf делает округление, что замечательно видно на скриншотах.
Теперь понятно почему ты не работаешь программистов cout<< и printf осуществляют форматный вывод, который зависит от спецификаторов настройки этого самого вывода
Цитата Сообщение от easybudda Посмотреть сообщение
std::setprecision(3)
- задал число знаков после запятой,

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
printf("%.0f RU %.0f KOP\r\n",fpart,100.0*spart);
- я настроил вывод без запятых, что тебе ещё не ясно???Хочешь узнать как осуществляется работа cout или printf - напиши разработчикам в мсдн и попроси код, тогда и поймёшь за форматированный вывод дабл. На сим считаю, что тема сама себя исчерпала...Если атврору топика нужно будет само число, никто ему не запрещает использовать sprintf c теми же спецификаторами вывода

Изначально раделение дабл на компоненты шло во всех вариантах , потом тебе не давало покоя что вывод копеек не тот, вот тебе его вывели, ну и что ты кипишь как чайник???

Добавлено через 7 минут
grizlik78, в завершение привожу апдейт кода, чтобы у тебя отпало желание спорить в этом топике - заметь без 0,5 + никаких циклов и прочих сложностей!
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
29
30
31
32
33
34
35
#include <stdio.h>
#include <conio.h>
#include <math.h>
 
char s[2];
 
int main()
{
    char ch;
    double val;
 
    double fpart;
    double spart;
    int kop;
    do
    {
        printf("Enter double\r\n");
        scanf("%lf",&val);
 
        fpart = floor(val);
        spart = val - fpart;
        printf("%.0f RU",fpart);
        sprintf(s,"%0.f",100.0*spart);
        sscanf(s,"%d",&kop);
        printf(" %d KOP\r\n",kop);
        
        printf("Celay chast' %lf\r\n",fpart);
        printf("Drobn chast' %lf\r\n",spart);
 
        printf("[Y/N] - Y - Enter new value\r\n");
        ch = getch();
    }
    while(ch == 'Y' || ch == 'y');
    return 0;
}
Добавлено через 1 минуту
Жду следующих язв
grizlik78
Эксперт С++
 Аватар для grizlik78
1887 / 1419 / 103
Регистрация: 29.05.2011
Сообщений: 2,967
03.08.2011, 16:21     непонятки #67
Да, последний код, наконец-таки, делает то, что нужно. Но делает он это посредством округления в (s)printf, нравится тебе это, или нет.

Не по теме:


Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
что тебе ещё не ясно???
Мне с самого начала абсолютно всё ясно. И почему некоторые программы не работают, и почему некоторые работают. На уровне машинного представления целых и дробных чисел.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
ну и что ты кипишь как чайник???
Я спокоен как бык

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
чтобы у тебя отпало желание спорить в этом топике
Да я что-то спора и не заметил. Из спора обычно обе стороны выгоду извлекают, у нас же никто. На этом и закончим.

-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 16:25     непонятки #68
Цитата Сообщение от grizlik78 Посмотреть сообщение
Но делает он это посредством округления в (s)printf, нравится тебе это, или нет.
Я с этим и не спорил, а этого добивался, сам за копейки начал...
Да думаю на сим на той теме надо ставить - CLOSED
grizlik78
Эксперт С++
 Аватар для grizlik78
1887 / 1419 / 103
Регистрация: 29.05.2011
Сообщений: 2,967
03.08.2011, 16:28     непонятки #69
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Я с этим и не спорил, а этого добивался, сам за копейки начал...
Дык ведь +0.5 делает это в десятки раз эффективнее, нежели printf.

Не по теме:

Вот блин, не сдержался. Ухожу-ухожу.

-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 16:53     непонятки #70
Цитата Сообщение от grizlik78 Посмотреть сообщение
Дык ведь +0.5 делает это в десятки раз эффективнее, нежели printf.
Чем эффективнее?+0,5 ты искажаешь введеное число, я считаю это неверным.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9382 / 5432 / 916
Регистрация: 25.07.2009
Сообщений: 10,428
03.08.2011, 17:20     непонятки #71
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Жду следующих язв
Всегда пожалуйста:
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
char s[2];
одна цифра только поместилась бы, а учитывая, что длинна строки в
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
sprintf(s,"%0.f",100.0*spart);
вообще никак не проверяется, скорее всего грохнется програмка...

Добавлено через 1 минуту
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Чем эффективнее?
видимо, тем, что простое арифметическое действие отработает быстрее, чем вызов двух функций (sprintf() + sscanf())...
-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 19:40     непонятки #72
Цитата Сообщение от easybudda Посмотреть сообщение
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);
- это эффективней, вызов цикла, возведение в степень, деление, преобразование типа...
Цитата Сообщение от easybudda Посмотреть сообщение
ss << std::fixed << std::setprecision(3) << d;
- остальные знаки наверное тоже не нужны?

Внимание сюрприз в Release версии нормально работает с s[2], забыл о мусоре в конце строк кода '\0' не поставил???Но если уж так хочешь чтобы всё было по букве закона можно s[3] поставить, сути єто НЕ ИЗМЕНИТ...
Миниатюры
непонятки  
-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 19:46     непонятки #73
Цитата Сообщение от easybudda Посмотреть сообщение
вообще никак не проверяется, скорее всего грохнется програмка...
Ну что проверил, грохнулась, видишь нет!
Жду новых замечаний
fasked
Эксперт C++
 Аватар для fasked
4925 / 2505 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
03.08.2011, 20:02     непонятки #74
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
в Release версии нормально работает с s[2]
Работает до поры до времени, видимо случайный ноль в памяти позволил программе не падать. Это несерьезно.
-=ЮрА=-
Заблокирован
Автор FAQ
03.08.2011, 20:09     непонятки #75
Я уже чуть выше об этом написал
Цитата Сообщение от fasked Посмотреть сообщение
аботает до поры до времени, видимо случайный ноль в памяти позволил программе не падать. Это несерьезно.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
чтобы всё было по букве закона можно s[3] поставить
PS:Какое отношение к разделению double на целую и дробную части с возможностью записать требуемое число знаков после запятой в инт это всё имеет???? Все посты построены на каких то нападках на мой код(видимо всем сложно признать что замудрённые алгоритмы всё же хуже), в то время как искажение ввода, вызов цикла, отбрасывание разрядов, ненужное приведение типа как бы приветсвуется, где тут справедливость, а главное логика????
fasked
Эксперт C++
 Аватар для fasked
4925 / 2505 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
03.08.2011, 20:37     непонятки #76
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Все посты построены на каких то нападках на мой код
Вы это сами спровоцировали, я бы даже сказал попросили об этом, разве нет?
grizlik78
Эксперт С++
 Аватар для grizlik78
1887 / 1419 / 103
Регистрация: 29.05.2011
Сообщений: 2,967
03.08.2011, 20:38     непонятки #77
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
в то время как искажение ввода, вызов цикла, отбрасывание разрядов, ненужное приведение типа как бы приветсвуется
В нижеследующей программе нет никакого искажения ввода. И циклов нет. А без приведения типов double в int не преобразовать. Монструозное преобразование через строку не в счёт.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <math.h>
 
#define ROUND(x) ( ( (x) < 0.0 ) ? ceil((x) - 0.5) : floor((x) + 0.5) )
 
int main()
{
    double val;
    int d1;
    int d2;
 
    printf("Input value: ");
    scanf("%lf", &val);
 
    d1 = (int)(val);
    d2 = (int)(ROUND((val - d1)*100));
 
    printf("val = %lg\n", val);
    printf("d1 = %d\n", d1);
    printf("d2 = %d\n", d2);
 
    return 0;
}
И ты считаешь алгоритм из строчек 15 и 16 (с использованием строки 4) замудрённым? Именно этот алгоритм приведён в шапке. И не я стал нападать на этот широко известный и применяемый метод.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9382 / 5432 / 916
Регистрация: 25.07.2009
Сообщений: 10,428
03.08.2011, 20:54     непонятки #78
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Ну что проверил, грохнулась, видишь нет!
Не, не грохнулось, что скорее странность, чем закономерность, я бы на такое не рассчитывал...

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Жду новых замечаний
попробуйте 1.9999999 ввести...

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Все посты построены на каких то нападках на мой код(видимо всем сложно признать что замудрённые алгоритмы всё же хуже), в то время как искажение ввода, вызов цикла, отбрасывание разрядов, ненужное приведение типа как бы приветсвуется, где тут справедливость, а главное логика?
Может дело всё-таки не в "замудрённости" других решений, и стоит прислушаться к тому, что Вам говорят?

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
pow(10.0, PRECISION));
Видимо, удивлю, но это константное выражение и будет оно вычислено один раз на этапе компиляции...

Добавлено через 14 минут
grizlik78, кстати,
Цитата Сообщение от easybudda Посмотреть сообщение
1.9999999
тоже неправильно отработает.
Вот без отбрасывания нулей
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 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
 
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 = (int64_t)tmp % (int64_t)(pow(10.0, PRECISION));
        printf("Int part: %lld  Fract part: %lld\n", iPart, fPart);
    }
    
    exit(0);
}
grizlik78
Эксперт С++
 Аватар для grizlik78
1887 / 1419 / 103
Регистрация: 29.05.2011
Сообщений: 2,967
03.08.2011, 21:19     непонятки #79
Цитата Сообщение от easybudda Посмотреть сообщение
тоже неправильно отработает.
Неправильно только в том смысле, что вместо 2 целых и 0 сотых получится 1 целая и 100 сотых. Но сумма то сходится Сто сотых можно и потом сократить, но в целом согласен. Правда я исходил из того, что исходное число вводится с двумя знаками точности. В этом случае целые будут представляться точно. Но если исходное значение вычисляется, то такая неприятность вполне вероятна.

Добавлено через 15 минут
Попробуем перекомпоновать. Вроде и временная переменная ушла и деление. Правда тут надо хорошо подумать, не пострадала ли хоть немножко область допустимых значений. Мой исходный вариант представляется мне немного надёжнее, но там придётся перенос осуществлять "вручную".
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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
 
int main(void){
        double val;
        
        while ( printf("> ") && scanf("%lf", &val) == 1 ){
                int64_t iPart = (int64_t)(val + 0.5*pow(10.0, -PRECISION));
                int64_t fPart = (int64_t)(signround((val - iPart)*pow(10.0, PRECISION)));
                printf("Int part: %lld  Fract part: %lld\n", iPart, fPart);
        }
        
        exit(0);
}
Хотя, баловство это всё
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2011, 21:46     непонятки
Еще ссылки по теме:

C++ Непонятки с bind2nd
C++ непонятки с for
C++ Непонятки с выводом
C++ Непонятки с указателями
Непонятки с рандомом C++

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

Или воспользуйтесь поиском по форуму:
castaway
Эксперт С++
4867 / 3006 / 370
Регистрация: 10.11.2010
Сообщений: 11,055
Записей в блоге: 10
Завершенные тесты: 1
03.08.2011, 21:46     непонятки #80
Ребят, вы похожи на скандальных бабок. 78 сообщений для обыденного вопроса - это слишком.
Никого не хочу обидеть но по-моему у вас нет личной жизни и вам доставляет удовольствие этот бесценный (именно бесценный, т.к. при таком количестве сообщений ни один нормальный новый пользователь данного форума не станет выяснять причину аналогичной проблемы копаясь в этом мусоре) флуд. Завязывайте.

* ответы принимаются автоматически, и каждый из них целиком и полностью будет подтверждать то что я изложил.

 Комментарий модератора 
Запрещено использовать нецензурные выражения в любом виде, оскорблять других участников форума, умышленно использовать выражения, противоречащие правилам русского языка.
Правила форума


Добавлено через 20 минут
Будда, ты только что уничтожил ровно половину смысла моего сообщения....
Yandex
Объявления
03.08.2011, 21:46     непонятки
Ответ Создать тему

Метки
округление
Опции темы

Текущее время: 23:01. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru