Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
27 / 27 / 18
Регистрация: 13.09.2014
Сообщений: 137
1

Умножение вещественных чисел, представенных как два int'a

05.09.2015, 01:11. Показов 2419. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пишу код по статье http://habrahabr.ru/company/xakep/blog/257897/
Написал сложение и вычитание.
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <cstdint>
class decimal
{
public:
    decimal() : m_integral{}, m_fractional{}
    {}
    decimal(double);
    decimal(int64_t, uint64_t);
    decimal(int64_t value) : m_integral(value), m_fractional{}
    {}
    decimal operator+(const decimal& other)const;
    decimal operator-(const decimal& other)const;
private:
    void normalize();
    uint64_t number_length(uint64_t)const;
private:
    int64_t m_integral;
    uint64_t m_fractional;
    static const uint64_t EXP1 = 0xAi64;//1E+1
    static const uint64_t EXP3 = 0x3E8i64;//1E+3
    static const uint64_t EXP18 = 0xDE0B6B3A7640000i64;//1E+18
};
uint64_t decimal::number_length(uint64_t n)const
{
    uint64_t count = 1;
    while (n /= EXP1) ++count;
    return count;
}
void decimal::normalize()
{
    uint64_t tail = m_fractional % EXP3;
    if (tail)
    {
        if (tail > (EXP3 / 2))
            m_fractional += (EXP3 - tail);
        else
            m_fractional -= tail;
    }
}
decimal::decimal(double value)
{
    if ((value > 0.0) && (value > static_cast<double>(INT64_MAX)))
        throw NULL;
    if ((value < 0.0) && (value < static_cast<double>(INT64_MIN)))
        throw NULL;
    m_integral = static_cast<int64_t>(std::floor(value));
    m_fractional = static_cast<int64_t>(std::floor((value - m_integral)*EXP18 + 0.5));
    normalize();
}
decimal::decimal(int64_t integral, uint64_t fractional)
{
    if (integral == INT64_MIN) throw NULL;
    if (fractional >= EXP18) throw NULL;
    if (integral < NULL)
    {
        if (fractional == NULL)
        {
            m_integral = integral;
            m_fractional = NULL;
        }
        else
        {
            m_integral = --integral;
            m_fractional = EXP18 - fractional * static_cast<uint64_t>(std::pow(EXP1, (18i64 - number_length(fractional))));
        }
    }
    else
    {
        m_integral = integral;
        m_fractional = fractional * static_cast<uint64_t>(std::pow(EXP1, (18i64 - number_length(fractional))));
    }
}
decimal decimal::operator+(const decimal& other)const
{
    decimal result;
    result.m_integral = this->m_integral + other.m_integral;
    if ((this->m_integral > NULL) && (other.m_integral > NULL) && (result.m_integral < NULL))
        throw NULL;
    if ((this->m_integral < NULL) && (other.m_integral < NULL) && (result.m_integral >= NULL))
        throw NULL;
    result.m_fractional = this->m_fractional + other.m_fractional;
    if (result.m_fractional >= EXP18)
    {
        result.m_fractional -= EXP18;
        (result.m_integral == INT64_MAX)
        ? throw NULL
        : ++result.m_integral;
    }
    return result;
}
decimal decimal::operator-(const decimal& other)const
{
    decimal result;
    if ((this->m_integral < NULL) && (other.m_integral > NULL))
    {
        if (this->m_integral == INT64_MIN) throw NULL;
        if ((static_cast<uint64_t>(std::abs(this->m_integral)) +
            static_cast<uint64_t>(other.m_integral)) > (static_cast<uint64_t>(INT64_MAX) + 1i64))
            throw NULL;
    }
    if ((this->m_integral > NULL) && (other.m_integral < NULL))
    {
        if (other.m_integral == INT64_MIN) throw NULL;
        if ((static_cast<uint64_t>(this->m_integral) +
            static_cast<uint64_t>(std::abs(other.m_integral))) > static_cast<uint64_t>(INT64_MAX))
            throw NULL;
    }
    result.m_integral = this->m_integral - other.m_integral;
    if (this->m_fractional >= other.m_fractional)
        result.m_fractional = this->m_fractional - other.m_fractional;
    else
    {
        result.m_fractional = (EXP18 - other.m_fractional) + this->m_fractional;
        if (result.m_integral == INT64_MIN) throw NULL;
        --result.m_integral;
    }
    return result;
}
Не могу разобраться с умножением. Может кто-нибудь привести пример кода умножения двух таких чисел или объяснить, что за формулы там написаны?
И для чего в описании операции деления нужен этот код из статьи?
C++
1
2
3
4
5
6
7
8
9
k = max(k): 1e+k <= a,
u = 1e+18, v = (a * 1e+18-k + b div 1e+k);
f = (u / v) * 1e+18-k,
for (++k; k <=18; ++k)
{
    u = (u % v) * 10;
    if (!u) break; // дальше будут нули
    f += u / v * 1e+(18-k);
}
Там выше сказано как найти X(число) в минус первой степени. Осталось умножить его только на второе число(т.е. реализовать умножение), как я понимаю.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.09.2015, 01:11
Ответы с готовыми решениями:

Организовать ввод двух вещественных чисел и операции над ними: сложение, вычитание, умножение и деление
Парни всем привет! Начинаю новую тему по решению задач Задача звучит так: Написать программу,...

Задать два числа как два массива и потом выполнить сложение, умножение и деление
Здравствуйте! Суть задачи в следующем: Нужно задать два числа как два массива и потом выполнить...

два файла вещественных чисел
Даны два файла вещественных чисел, в которых данные отсортированы по неубыванию. Сформируйте...

Даны два файла вещественных чисел с именами S1 и S2
Нужна помощь, люди добрые, на С++. Времени разбираться, как сделать, совсем уже нету( Даны два...

2
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
05.09.2015, 09:07 2
Пока дочитал только до умножения и обнаружил ошибку в следующем тексте:

<
Введем матрицу для упрощения вычисления умножения:

U = (a1, a2, b1, b2),
V = (c1, c2, d1, d2)T,
A = V * U,
A=
| a1*c1 a1*c1 b1*c1 b2*c1 |
| a1*c2 a1*c2 b1*c2 b2*c2 |
| a1*d1 a1*d1 b1*d1 b2*d1 |
| a1*d2 a1*d2 b1*d2 b2*d2 |
>

На самом деле во втором столбце матрицы вместо a1 должно стоять a2.
0
27 / 27 / 18
Регистрация: 13.09.2014
Сообщений: 137
05.09.2015, 13:45  [ТС] 3
Mr.X, если разберетесь с умножением, напишите, пожалуйста.
Цитата:
Здесь 103 является, по сути, той погрешностью, за которой double перестает быть точным.
. 103 это 10 в 3 степени. (и в коде так же)
0
05.09.2015, 13:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.09.2015, 13:45
Помогаю со студенческими работами здесь

Создать два класса: вещественные числа и вектор вещественных чисел
Создать два класса: вещественные (Float) и вектор (float*). Определить конструкторы - по умолчанию,...

Умножение вещественных чисел
Здравствуйте. Подскажите пожалуйста double c = 8.9 * 8.9; e.setText(Double.toString(c)); ...

Как сравнить два одномерных массива вещественных чисел?
Объясните, пожалуйста, в чём заключается особенность сравнения двух одномерных массивов...

Неточное умножение вещественных чисел
Помогите, пожалуйста! Мне нужно умножить 0.95 на 60 при заданном режиме округления - &quot;отбрасывание...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru