Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Десятичная дробь - не понятки... лучше загляни чтоб понять :) 
:(
    Опции темы
ressac
  Дата 19.12.2006, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



привет всем. ;)


Код


#include <stdio.h>

main()
{
 int i,num; float num_f,a,b;
 printf("Enter the number: "), scanf("%f",&num_f);
 for(i=1;num_f;i++)
 {
  printf("\n\n%.80f",num_f);
  
  num_f*=10; //printf("\n\n%.80f",num_f);
  
  num=num_f; //printf("\n\n%d",num);
  
  num_f-=num; //printf("\n\n%.80f",num_f);
  
  
  printf("\n ------\nFINAL\n ------\nI:%d Num_f: %.80f\n---------",i,num_f);

  system("pause");
 }

system("pause");
}



Вот прога которая по идее должна считать сколько цифр после запятой, на теории всё работает , а вот на практике нет smile
например я ввожу цифру "0.01" а реально получаю вот что ---> "0.00999999977648258210000000000000000000000000000000000000000000000000000000000000" или "0.1"  а получаю "0.10000000149011612000000000000000000000000000000000000000000000000000000000000000"

так вот вопрос в том, откуда берутся эти левый цифры? 
в них вся проблема , если бы их не было цикл повторялся ровно столько сколько есть цифр в ведёном номере тойсть если "0.1" то он и повторится один раз но так как появляются другие цифры то ясно что он и будет повторятся больше чем один раз smile
короче SOMEBODY  HELP  ME PLEASE smile  smile 

спасибо пока. ;)

p.s. там ещё принтфы я напихал, это для того чтоб было наглядно видно что мы имеем после каждой операции. Я юзаю gcc компиль может в борлонде будет всё по другому хз.
PM MAIL   Вверх
nickless
Дата 19.12.2006, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(ressac @ 19.12.2006,  19:19)
откуда берутся эти левый цифры? 

Компьютер хранит числа в двоичной системе и с ограниченной точностью, поэтому числа, которые не возможно точно представить в двоичной системе, округляются. 
Hапример 1/10=1/(2*5), 5 на 2 не делится.
Если тебе не обязательно надо float, считывай в char* и считай цифры там, или сначала округляй float, пиши его в char* и считай там.

Это сообщение отредактировал(а) nickless - 19.12.2006, 20:38


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
sergejzr
Дата 19.12.2006, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Возможных десятичных чисел - бесконечное количество, а вот бит для представления - количество очень даже ограниченное (32). Из этого следует, что невозможно любую десятичную дробь точно представить. Поэтому числа и "округляются"


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
ressac
Дата 19.12.2006, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



nickless
не совсем тебя понял насчёт char
PM MAIL   Вверх
nickless
Дата 19.12.2006, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(ressac @ 19.12.2006,  19:59)
не совсем тебя понял насчёт char

Я имел ввиду число просто как строку сохранить, а потом просто посчитать сколько букв между точкой/запятой и концом строки.
Код
    char str[64];
    printf("Enter the number: "), scanf("%s", str);
// тут считать



--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Dov
Дата 19.12.2006, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Цитата(ressac @  19.12.2006,  19:19 Найти цитируемый пост)
так вот вопрос в том, откуда берутся эти левый цифры? 

Отсюда
Код
printf("\n\n%.80f",num_f);
А точнее отсюда
Код
%.80f

Ты указал точность: 80 знаков после запятой.



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
W4FhLF
Дата 19.12.2006, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Всё дело в том, что в данном случае тип float есть короткий формат представления дробных чисел в памяти, точность вычисления 6 знаков после запятой, после чего идёт округление самим арифметическим сопроцессором, при расчёте дробной части всё, что после 6 знака просто не учитывается, поэтому выводить 80 знаков после запятой не имеет никакого смысла. Максимальная точность у расширенного формата, там точность достигает 19 знаков после запятой. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
nickless
Дата 19.12.2006, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(Dov @ 19.12.2006,  20:53)
Ты указал точность: 80 знаков после запятой.

Даже если поставить 4 знака, считать всё равно будет неправильно, потому что число каждый раз округляется.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
ressac
Дата 19.12.2006, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



Цитата(nickless @  19.12.2006,  19:39 Найти цитируемый пост)
Я имел ввиду число просто как строку сохранить, а потом просто посчитать сколько букв между точкой/запятой и концом строки.

для этого вроде таблица нужна, или нет? если нет то каким образом считать.

Цитата(Dov @  19.12.2006,  19:53 Найти цитируемый пост)
Ты указал точность: 80 знаков после запятой.

это форма представления числа на экране, если я даже удалю из кода ".80" у меня серовно исход будет тот-же самый.


Цитата(W4FhLF @  19.12.2006,  19:53 Найти цитируемый пост)
Максимальная точность у расширенного формата, там точность достигает 19 знаков после запятой.  

если ты про double тот там тот-же исход, разве что в некоторых случаях слегка другой..
PM MAIL   Вверх
nickless
Дата 19.12.2006, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(ressac @ 19.12.2006,  21:15)
для этого вроде таблица нужна, или нет? если нет то каким образом считать.

Tаблица?
Инициализируешь num нулём, смотришь длину строки, в цикле с конца пропускаешь нули, потом увеличиваешь num, пока не найдешь точку, а если не найдешь, значит num = 0...


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
ressac
Дата 19.12.2006, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



nickless
я вообщем не понял, о чём ты говоришь, я наверно просто ещё не знаком с этим, если тебе не трудно преведи малый пример. спасибо..
PM MAIL   Вверх
nickless
Дата 19.12.2006, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Код

#include <stdio.h>
#include <string.h>
main()
{
    int i, num;
    char str[64];
    printf("Enter the number: "), scanf("%s", str);
    printf("%s\n", str);

    num = 0;
    for (i=strlen(str)-1; i>=0; i--)
    {
        if (str[i] == '0')  // пропускаем нули в конце
            continue;
        if ((str[i] == '.') || (str[i] == '.'))
            break;          // нашли точку/запятую

        num++;

        if (i == 0)
            num = 0;      // не нашли точку/запятую
    }

    printf ("%d\n", num);

    return 0;



--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
ressac
Дата 19.12.2006, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



nickless
в принципе понял, я это ещё просто не изучал smile
интересно.
вот только одно не пойму зачем ты тут "i=strlen(str)-1" ставишь минус один?

спасибо smile
PM MAIL   Вверх
nickless
Дата 19.12.2006, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(ressac @ 19.12.2006,  22:36)
вот только одно не пойму зачем ты тут "i=strlen(str)-1" ставишь минус один?

Потому что массивы в C(++) с нуля начинаются, первая буква находится в str[0], последняя в str[length-1]

Это сообщение отредактировал(а) nickless - 19.12.2006, 23:46


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Dov
Дата 20.12.2006, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Код
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
    char  buf[81];
    char  num_f[81];
    char* p;
    int   count = 0;

    printf("Enter the number: ");
    scanf("%s", buf);
    sscanf(buf, "%s", num_f);

    if(strchr(num_f, '.'))
    {
        p = num_f + strlen(num_f) - 1;
        while(*p == '0')
            p--;
        while(isdigit(*p--))
            count++;
    }
    printf("\ncount: %d\n", count);

    return 0;
}



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0641 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.