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

Есть ли класс для работы с дробными/смешанными числами? - C++

Восстановить пароль Регистрация
 
Van111
кодер с++
208 / 187 / 4
Регистрация: 03.08.2011
Сообщений: 2,585
Записей в блоге: 12
04.05.2013, 15:15     Есть ли класс для работы с дробными/смешанными числами? #1
собственно есть ли такой готовый(то есть протестированный) класс?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.05.2013, 15:15     Есть ли класс для работы с дробными/смешанными числами?
Посмотрите здесь:

C++ Класс для работы с комплексными числами
Класс для работы с большими числами C++
C++ Описать класс для работы с комплексными числами
C++ Класс Complex для работы с комплексными числами
C++ Описать класс для работы с числами
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
05.05.2013, 02:39     Есть ли класс для работы с дробными/смешанными числами? #2
Цитата Сообщение от Van111 Посмотреть сообщение
собственно есть ли такой готовый(то есть протестированный) класс?
Не понятно, что вы имеете в виду. Все когда-то кто-то написал.
Если ваш критерий "готовности" -- протестированность кода, то что мешает самостоятельно набросать юнит-тесты к функционалу?

В общем странно. Если вам для учебы -- возьмите первый попавшийся код.
Кликните здесь для просмотра всего текста
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
#include <iostream>
 
long int getGcd(long int a, long int b) {
  if (a < 0) a = -a;
  if (b < 0) b = -b;
  if (a == b) {
    return a;
  }
  if (a > b) {
    return getGcd(a - b, b);
  } else {
    return getGcd(a, b - a);
  }
}
 
class Fraction {
 public:
  Fraction() : nominator(0), denominator(-1) {}
  Fraction(long int nominator, long int denominator)
    : nominator(nominator), denominator(denominator) {
    simplify();
  }
  Fraction(long int number) : nominator(number), denominator(1) {}
  long int getNominator() const { return nominator; }
  long int getDenominator() const { return denominator; }
  double toDouble() const {
    return static_cast<double>(nominator) / denominator;
  }
 protected:
  void simplify() {
    if (denominator < 0) {
      nominator = -nominator;
      denominator = -denominator;
    }
    long int gcd = getGcd(nominator, denominator);
    nominator /= gcd;
    denominator /= gcd;
  }
 private:
  long int nominator, denominator;
};
 
std::ostream &operator<<(std::ostream &stream, const Fraction &f) {
  return stream << f.getNominator() << "/" << f.getDenominator();
}
 
Fraction operator+(const Fraction &a, const Fraction &b) {
  return Fraction(a.getNominator() * b.getDenominator() +
    a.getDenominator() * b.getNominator(),
    a.getDenominator() * b.getDenominator());
}
 
Fraction operator-(const Fraction &a, const Fraction &b) {
  return Fraction(a.getNominator() * b.getDenominator() -
    a.getDenominator() * b.getNominator(),
    a.getDenominator() * b.getDenominator());
}
 
Fraction operator*(const Fraction &a, const Fraction &b) {
  return Fraction(a.getNominator() * b.getNominator(),
    a.getDenominator() * b.getDenominator());
}
 
Fraction operator/(const Fraction &a, const Fraction &b) {
  return Fraction(a.getNominator() * b.getDenominator(),
    a.getDenominator() * b.getNominator());
}
 
int compare(const Fraction &a, const Fraction &b) {
  return a.getNominator() * b.getDenominator() -
    b.getNominator() * a.getDenominator();
}
 
bool operator<(const Fraction &a, const Fraction &b) {
  return compare(a, b) < 0;
}
 
bool operator<=(const Fraction &a, const Fraction &b) {
  return compare(a, b) <= 0;
}
 
bool operator>(const Fraction &a, const Fraction &b) {
  return compare(a, b) > 0;
}
 
bool operator>=(const Fraction &a, const Fraction &b) {
  return compare(a, b) >= 0;
}
 
bool operator==(const Fraction &a, const Fraction &b) {
  return compare(a, b) == 0;
}
 
bool operator!=(const Fraction &a, const Fraction &b) {
  return compare(a, b) != 0;
}
 
int main(int argc, char *argv[]) {
  Fraction a(145, 374), b(285, 737);
  std::cout << "a = " << a << ", b = " << b << std::endl;
  std::cout << "a - b = " << a - b << std::endl; 
  std::cout << "a + b = " << a + b << std::endl; 
  std::cout << "a * b = " << a * b << std::endl; 
  std::cout << "a / b = " << a / b << std::endl; 
  return 0;
}
Van111
кодер с++
208 / 187 / 4
Регистрация: 03.08.2011
Сообщений: 2,585
Записей в блоге: 12
05.05.2013, 19:07  [ТС]     Есть ли класс для работы с дробными/смешанными числами? #3
Цитата Сообщение от lemegeton Посмотреть сообщение
В общем странно. Если вам для учебы -- возьмите первый попавшийся код.
нет, мне для взаимодействия небесных тел, точнее чтобы идеально представить силы взаимодействия, тем самым избежав столкновений которых не должно быть.

Добавлено через 1 минуту
Цитата Сообщение от lemegeton Посмотреть сообщение
то что мешает
лень, не хочется отвлекатся от основной задачи
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
05.05.2013, 21:29     Есть ли класс для работы с дробными/смешанными числами? #4
Есть вот такой код. Писался где-то полтора года назад. Работает в продакшене. Вроде пока глюков нет. Да и откуда им взяться при таком минимализме!?

Ессессенно, не в том же виде, что и на проекте, ибо проприетарщина, но без кардинальных изменений в коде.
Жабадоки, все дела, корпорэйт-вэй, чо.
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#include <cmath>
 
namespace Math {
 
  /**
   * Calculates GCD of two objects with Euclidian division method.
   * Requres parameters to be comparable with "<" operator, and
   * to be substractable.
   * <p>
   * Returns 1 if either of parameters is zero.
   * 
   * @param a first object.
   * @param b second object.
   * @return value, representing GCD of two passed objects.
   */
  template <class ValueType>
  ValueType getGcd(ValueType a, ValueType b) {
    if (a == 0 || b ==0) {
      return 1;
    }
    if (a < 0) {
      a = -a;
    }
    if (b < 0) {
      b = -b;
    }
    while (a != b) {
      if (a < b) {
        b -= a;
      } else {
        a -= b;
      }
    }
    return a;
  }
 
  /**
   * Immutable class representing a fraction.
   * 
   * @param ValueType type of numerator and denominator, should be signed.
   */
  template <class ValueType = long int>
  class Fraction {
   public:
 
    /**
     * Default class constructor. Set fraction to 0/1.
     */
    Fraction() : numerator(0), denominator(1) {}
 
    /**
     * Class constructor with one parameter. Set fraction to value/1.
     * Is also used to convert ValueType to a fraction.
     * 
     * @param value value to set fraction to.
     */
    Fraction(const ValueType &value) : numerator(value), denominator(1) {}
 
    /**
     * Class constructor with two parameters. Sets fraction to
     * numerator/denominator.
     * 
     * @param numerator value of fraction numerator.
     * @param denominator value of fraction denomintator.
     */
    Fraction(const ValueType &numerator, const ValueType &denominator)
      : numerator(numerator), denominator(denominator) {}
 
    /**
     * Getter for numerator value.
     * 
     * @return value of fraction numerator.
     */
    const ValueType &getNumerator() const {
      return numerator;
    }
 
    /**
     * Getter for denominator value.
     * 
     * @return value of fraction denominator.
     */
    const ValueType &getDenominator() const {
      return denominator;
    }
   private:
    ValueType numerator;
    ValueType denominator;
  };
 
  /**
   * Reduces fraction, removing GCD from both numerator and
   * denominator and simplifying fraction sign.
   * 
   * @param fraction a fraction to reduce.
   * @return reference to self object.
   * @see Fraction
   */
  template <class T>
  Fraction<T> reduce(const Fraction<T> &fraction) {
    T gcd = getGcd(fraction.getNumerator(), fraction.getDenominator());
    T numerator = fraction.getNumerator() / gcd;
    T denominator = fraction.getDenominator() / gcd;
    if (denominator < 0) {
      numerator = -numerator;
      denominator = -denominator;
    }
    return Fraction<T>(numerator, denominator);
  }
 
  /**
   * Addition operator for two fractions.
   * 
   * @param a first component.
   * @param b second component.
   * @return a fraction that is a sum of two fractions. 
   */
  template <class T>
  Fraction<T> operator+(const Fraction<T> &a, const Fraction<T> &b) {
    return Fraction<T>(a.getNumerator() * b.getDenominator() +
      a.getDenominator() * b.getNumerator(),
      a.getDenominator() * b.getDenominator());
  }
 
  /**
   * Subtraction operator for two fractions.
   * 
   * @param a minuend fraction.
   * @param b subtrahend fraction.
   * @return a fraction that is a difference of two minuend and subtrahend.
   */
  template <class T>
  Fraction<T> operator-(const Fraction<T> &a, const Fraction<T> &b) {
    return Fraction<T>(a.getNumerator() * b.getDenominator() -
      a.getDenominator() * b.getNumerator(),
      a.getDenominator() * b.getDenominator());
  }
 
  /**
   * Multiplication of two fractions.
   * 
   * @param a first multiplier.
   * @param b second multiplier.
   * @return product of two multipliers.
   */
  template <class T>
  Fraction<T> operator*(const Fraction<T> &a, const Fraction<T> &b) {
    return Fraction<T>(a.getNumerator() * b.getNumerator(),
      a.getDenominator() * b.getDenominator());
  }
 
  /**
   * Division of two fractions.
   * 
   * @param a dividend fraction.
   * @param b divisor fraction.
   * @return a fraction that is a quotent of two divident and divisor.
   */
  template <class T>
  Fraction<T> operator/(const Fraction<T> &a, const Fraction<T> &b) {
    return Fraction<T>(a.getNumerator() * b.getDenominator(),
      a.getDenominator() * b.getNumerator());
  }
 
  /**
   * Negation operator for a fraction.
   * 
   * @param fraction a given fraction.
   * @return a fraction with an opposite sign.
   */
  template <class T>
  Fraction<T> operator-(const Fraction<T> &fraction) {
    return Fraction<T>(-fraction.getNumerator(), fraction.getDenominator());
  }
 
  /**
   * C-style comparision function for two fractions.
   * 
   * @param a left operand.
   * @param b right operand.
   * @return a negative value if left operand is greater, a zero if
   *         operands are equal and a positive value if right operand
   *         is greater.
   */
  template <class T>
  T compare(const Fraction<T> &a, const Fraction<T> &b) {
    return a.getNumerator() * b.getDenominator() - a.getDenominator() *
      b.getNumerator();
  }
 
  /**
   * Convinient operator to check if a fraction is less than another
   * fraction.
   * 
   * @param a left component.
   * @param b right component
   * @return true if left component is less than the right one.
   */
  template <class T>
  bool operator<(const Fraction<T> &a, const Fraction<T> &b) {
    return compare(a, b) < 0;
  }
 
  /**
   * Convinient operator to check if a fraction is less than or equal to
   * another fraction.
   * 
   * @param a left component.
   * @param b right component
   * @return true if left component is less than or equal to the right one.
   */
  template <class T>
  bool operator<=(const Fraction<T> &a, const Fraction<T> &b) {
    return compare(a, b) <= 0;
  }
 
  /**
   * Convinient operator to check if a fraction is greater than another
   * fraction.
   * 
   * @param a left component.
   * @param b right component
   * @return true if left component is greater than the right one.
   */
  template <class T>
  bool operator>(const Fraction<T> &a, const Fraction<T> &b) {
    return compare(a, b) > 0;
  }
 
  /**
   * Convinient operator to check if a fraction is greater than or equal to
   * another fraction.
   * 
   * @param a left component.
   * @param b right component
   * @return true if left component is greater than or equal to the right one.
   */
  template <class T>
  bool operator>=(const Fraction<T> &a, const Fraction<T> &b) {
    return compare(a, b) >= 0;
  }
 
  /**
   * Convinient operator to check if a fraction is equal to another fraction.
   * It uses the same compare function, since reducing may cause
   * performance issues.
   * 
   * @param a left component.
   * @param b right component
   * @return true if left component is equal to the right one.
   */
  template <class T>
  bool operator==(const Fraction<T> &a, const Fraction<T> &b) {
    return compare(a, b) == 0;
  }
 
  /**
   * Convinient operator to check if a fraction is not equal to another
   * fraction.
   * It uses the same compare function, since reducing may cause
   * performance issues.
   * 
   * @param a left component.
   * @param b right component
   * @return true if left component is not equal to the right one.
   */
  template <class T>
  bool operator!=(const Fraction<T> &a, const Fraction<T> &b) {
    return compare(a, b) != 0;
  }
 
  /**
   * Computes power of a fraction.
   * 
   * @param fraction fraction to get power of.
   * @param power power to return fraction in.
   * @return fraction in power of power.
   */
  template <class T>
  Fraction<T> pow(const Fraction<T> &fraction, const T &power) {
    // optimization for a common use case
    if (power == 0) {
      return 1;
    }
    Fraction<T> result(std::pow(fraction.getNumerator(), std::abs(power)),
        std::pow(fraction.getDenominator(), std::abs(power)));
    return ((power < 0) ? (Fraction<T>(1) / result) : result);
  }
 
  /**
   * Calculates absolute value of a fraction.
   * 
   * @param fraction a fraction.
   * @return a fraction that represent an absolute value of a fraction.
   */
  template <class T>
  Fraction<T> abs(const Fraction<T> &fraction) {
    return Fraction<T>(std::abs(fraction.getNumerator()),
      std::abs(fraction.getDenominator()));
  }
 
}
Пример.

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
#include "Math/fraction.hpp"
#include <iostream>
 
template <class T>
std::ostream &operator<<(std::ostream &stream, const Math::Fraction<T> &fraction) {
  Math::Fraction<T> f = Math::reduce(fraction);
  return stream << f.getNumerator() << "/" << f.getDenominator();
}
 
int main(int argc, char *argv[]) {
  std::cout << "Simple math:" << std::endl;
 
  Math::Fraction<int> a(881, -7716), b(127, 343);
  std::cout << "a = " << a << ", b = " << b << std::endl;
  std::cout << "a - b = " << a - b << std::endl;
  std::cout << "a + b = " << a + b << std::endl;
  std::cout << "a * b = " << a * b << std::endl;
  std::cout << "a / b = " << a / b << std::endl;
  std::cout << "-a = " << -a << std::endl;
  std::cout << "a ^ 2 = " << pow(a, 2) << std::endl;
  std::cout << "a ^ -2 = " << pow(a, -2) << std::endl;
  std::cout << "abs(a) = " << abs(a) << std::endl;
 
  std::cout << "Comparisions:" << std::endl;
 
  std::cout << "a < b = " << ((a < b) ? "true" : "false") << std::endl;
  std::cout << "a <= b = " << ((a <= b) ? "true" : "false") << std::endl;
  std::cout << "a > b = " << ((a > b) ? "true" : "false") << std::endl;
  std::cout << "a >= b = " << ((a >= b) ? "true" : "false") << std::endl;
  std::cout << "a == b = " << ((a == b) ? "true" : "false") << std::endl;
  std::cout << "a != b = " << ((a != b) ? "true" : "false") << std::endl;
 
  return 0;
};
Yandex
Объявления
05.05.2013, 21:29     Есть ли класс для работы с дробными/смешанными числами?
Ответ Создать тему
Опции темы

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