Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Преобразовать строку в double  (Прочитано 12907 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sss
Специалист

ru
Offline Offline

« : 27-11-2006 09:54 » 

Привет всем.
Возник такой вопрос. Преобразовать текстовую строку (без использования стандартных средств) типа "12.05" в double понятно как. А вот , например, "12.05E+100" непонятно. Экспонента в double лежит в виде 2^X. Не могу понять, как привести десятичную степень E+100 к 2^X Не понял
Записан

while (8==8)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #1 : 27-11-2006 15:05 » 

sss, то что после E в твоём случае это 10^x
а 2 в стпени x можно задать вот так 1<<x Улыбаюсь
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 27-11-2006 18:41 » 

sss, а зачем к двоичной системе приводить, если у тебя текстовая запись - десятичная? Просто возведи 10 в нужную степень.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #3 : 28-11-2006 01:40 » 

Что бы ответить на Ваши вопросы я лучше рассмотрю пример.

Формат бит числа double (IEEE Standard 754):
Код:
    
    seeeeeeeeeeemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

  , где  s - знак числа ( 1 бит);
          e - экспонента со смещением 1023  (11 бит);
          m - мантисса (52 бит).

Нормализованное значение числа, зашифрованного в этом виде:
                     V = (-1)^s 2^e × 1.f (normalized)

Цитата:  Илья Государев

Дано 48.625 = 32 + 16 + 1/2 + 1/8 = 110000.101 = 110000.101 * 1 = 110000.101 * 2^0
Чтобы представить в нормализованном виде, нужно перенести запятую после первой его
цифры. Это будет просто единица для числа с целой частью и первая единица после
запятой (первая значащая) для дроби без целой части.
После этого нужно скорректировать порядок.
110000.101 * 2^0 = 1.10000101 * 2^5
Прибавим к порядку 5 смещение 1023, получается 1028. Это число как раз из 11 цифр в
двоичной форме: 10000000100
Все, что после точки - наша мантисса.
Формируем цепочку бит слева направо начиная от 63-го.
бит 63 будет нулевым, так как число положительное.
Биты 62…52 - наш порядок 10000000100
С бита 51 пошла мантисса: 1000010100000000000000000000000000000000000000000000
Итого:
0 10000000100 10000101 00000000000000000000000000000000000000000000


  Т.е. все понятно. Дальше я встрял. А если число задано как 48.625E+100 ? Я не могу сформулировать внятно задачи. Допустим, что это число 48.625E+1.  Тогда можно убрать десятичную экспоненту и раскладывать на двоичные дроби  число 486.25 = 111100110.01. А если десятичная экспонента большая положительная? Получается, что дробей не будет и задача превращается в нахождение дополнительного сдвига. А если отрицательная большая?
« Последнее редактирование: 28-11-2006 02:12 от sss » Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #4 : 28-11-2006 03:49 » 

Пришла в полено идея. Раскладывать 10^x на 2^x*5^x. Допустим.

  0.01 = 2^-2 * 5^-2
   0.1 = 2^-1 * 5^-1
   10 = 2^1 * 5^1;
   100 = 2^2 * 5^2
  ...
   10^x = 2^x * 5^x

Тогда при формировании мантиссы, предварительно формировать 28.625E100 = 28.625 x 5^100 * 2^100. Один фиг 28.625 x 5^100 слишком гигантское число для разложения на дроби. 8o(
Записан

while (8==8)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 28-11-2006 06:24 » 

sss, извини меня тупого, но я не понимаю, что тебе нужно - разложить на состовляющие или все таки получить число из строки?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #6 : 28-11-2006 06:38 » 

sss, если тебе нужно именно, то, что заявлено в теме почиму бы не воспользоваться средсвами библиотек
stringstream >> double
atoi и собратьями
boost::spirit
прочим
Записан

Странно всё это....
sss
Специалист

ru
Offline Offline

« Ответ #7 : 28-11-2006 06:59 » 

LogRus а самому не интересно?

RXL прочти пожалуйста внимательно пример от Государева. Что бы получить число double в формате IEEE 754 мы должны представить мантиссу в виде двоичной дроби (разложить по степеням двойки) и экспоненту в виде 2^x.
Записан

while (8==8)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 28-11-2006 07:18 » 

sss, мне обычно интересней meta программирование, фабрики, синглетоны и тому подобное.
Записан

Странно всё это....
sss
Специалист

ru
Offline Offline

« Ответ #9 : 28-11-2006 07:20 » 

Нельзя объять необъятное....
Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #10 : 28-11-2006 09:03 » 

Как я понимаю, в случае с E+100 задача сводится к нахождению верхних 52 (53) бит результата умножения больших чисел и вычислению количества отброшенных бит.
Например:
  Дано: Длина мантиссы = 8 бит
           Входное число   = 15 x E+2
 Решение:
       15 x 100 = 1500 = 10111011(100)b  // (100) - лишняя часть. Не хватает мощности мантиссы (8 бит)
       ненормализованная мантисса = 10111011b
       Отброшено 3 бита, поэтому экспонента = 2^3
       нормализованная мантисса = 0111011b и экспонента становиться равной 2^3 * 2^7 = 2^10
       Искомое число в формате IEEE: (-1)^0 x 2^10 x 1.0111011
       Потеря точности = 100b = 4

Непонятно: 

  Как найти верхние 52 бит результата умножения чисел типа 2.64 x 10^100 ?

   
« Последнее редактирование: 28-11-2006 09:06 от sss » Записан

while (8==8)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines