Skip to content

Commit d45f508

Browse files
authored
[decimal] Add __abs__ and __float__ to implement Absable and Floatable methods (#12)
- Add `__abs__` and `__float__` to implement `Absable` and `Floatable` methods. - Fix a bug in `__int__` which does not print floats.
1 parent 23b116c commit d45f508

File tree

8 files changed

+397
-489
lines changed

8 files changed

+397
-489
lines changed

README.md

Lines changed: 110 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ Rome is not built in one day. DeciMojo is currently under active development. Co
2020

2121
## Examples
2222

23-
Here presents 10 key examples of how to use the `Decimal` type with the most common operations.
23+
Here are 10 key examples of how to use the `Decimal` type with the most important features.
2424

2525
### 1. Creating Decimals
2626

2727
```mojo
28-
from decimojo import Decimal
28+
from decimojo.prelude import *
2929
3030
# From string with various formats
3131
var d1 = Decimal("123.45") # Regular decimal
@@ -36,11 +36,11 @@ var d4 = Decimal("1_000_000.00") # Readable format with underscores
3636
# From integers and floats
3737
var d5 = Decimal(123) # Integer
3838
var d6 = Decimal(123.45) # Float (approximate)
39-
var d7 = Decimal(123.45, max_precision=True) # Float with maximum precision
4039
41-
# From components
42-
var d8 = Decimal(12345, 0, 0, False, 2) # 123.45 (coefficient 12345, scale 2)
43-
var d9 = Decimal(12345, 0, 0, True, 2) # -123.45 (negative flag set)
40+
# Special values
41+
var max_val = Decimal.MAX() # 79228162514264337593543950335
42+
var min_val = Decimal.MIN() # -79228162514264337593543950335
43+
var zero = Decimal.ZERO() # 0
4444
```
4545

4646
### 2. Basic Arithmetic Operations
@@ -61,165 +61,156 @@ var quot = Decimal("123.45") / Decimal("2.5") # 49.38
6161
# Negation
6262
var neg = -Decimal("123.45") # -123.45
6363
64-
# Power (exponentiation)
65-
var squared = Decimal("2.5") ** 2 # 6.25
66-
var cubed = Decimal("2") ** 3 # 8
67-
var reciprocal = Decimal("2") ** (-1) # 0.5
64+
# Absolute value
65+
var abs_val = abs(Decimal("-123.45")) # 123.45
6866
```
6967

70-
### 3. Rounding with Different Modes
68+
### 3. Exponentiation (Power Functions)
7169

7270
```mojo
73-
from decimojo import Decimal
74-
from decimojo.rounding_mode import RoundingMode
75-
from decimojo.mathematics import round
76-
77-
var num = Decimal("123.456789")
78-
79-
# Round to various decimal places with different modes
80-
var default_round = round(num, 2) # 123.46 (HALF_EVEN)
81-
var down = round(num, 2, RoundingMode.DOWN()) # 123.45 (truncate)
82-
var up = round(num, 2, RoundingMode.UP()) # 123.46 (away from zero)
83-
var half_up = round(num, 2, RoundingMode.HALF_UP()) # 123.46 (≥0.5 rounds up)
84-
85-
# Rounding special cases
86-
var half_value = round(Decimal("123.5"), 0) # 124 (banker's rounding)
87-
var half_odd = round(Decimal("124.5"), 0) # 124 (banker's rounding to even)
71+
# Integer exponents
72+
var squared = Decimal("2.5") ** 2 # 6.25
73+
var cubed = Decimal("2") ** 3 # 8
74+
var tenth_power = Decimal("2") ** 10 # 1024
75+
76+
# Negative exponents
77+
var reciprocal = Decimal("2") ** (-1) # 0.5
78+
var inverse_square = Decimal("2") ** (-2) # 0.25
79+
80+
# Special cases
81+
var anything_power_zero = Decimal("123.45") ** 0 # 1
82+
var one_power_anything = Decimal("1") ** 100 # 1
83+
var zero_power_positive = Decimal("0") ** 5 # 0
8884
```
8985

90-
### 4. Working with Scale and Precision
86+
### 4. Type Conversions
9187

9288
```mojo
93-
var d = Decimal("123.45") # Scale is 2
94-
print(d.scale()) # Prints: 2
89+
var d = Decimal("123.456")
9590
96-
# Changing scale through rounding
97-
var more_precise = round(d, 4) # 123.4500
98-
print(more_precise.scale()) # Prints: 4
91+
# String conversion
92+
var str_val = String(d) # "123.456"
9993
100-
var less_precise = round(d, 1) # 123.5 (rounds up)
101-
print(less_precise.scale()) # Prints: 1
94+
# Integer conversion (truncates toward zero)
95+
var int_val = Int(d) # 123
10296
103-
# Scale after operations
104-
var a = Decimal("123.45") # Scale 2
105-
var b = Decimal("67.890") # Scale 3
106-
print((a + b).scale()) # Prints: 3 (takes the larger scale)
107-
print((a * b).scale()) # Scale becomes 5 (sum of scales)
97+
# Float conversion
98+
var float_val = Float64(d) # 123.456
99+
100+
# Check if value can be represented as an integer
101+
var is_int = d.is_integer() # False
102+
var whole_num = Decimal("100.000")
103+
var is_whole = whole_num.is_integer() # True
108104
```
109105

110-
### 5. Zero and Special Values
106+
### 5. Working with Scale and Precision
111107

112108
```mojo
113-
# Different ways to represent zero
114-
var z1 = Decimal("0") # 0
115-
var z2 = Decimal("0.00") # 0.00
116-
print(z1.is_zero(), z2.is_zero()) # Both print: True
109+
var d = Decimal("123.45")
110+
var scale_val = d.scale() # 2 (number of decimal places)
117111
118-
# Special values from static methods
119-
var max_val = Decimal.MAX() # 79228162514264337593543950335
120-
var min_val = Decimal.MIN() # -79228162514264337593543950335
121-
var one = Decimal.ONE() # 1
122-
var neg_one = Decimal.NEGATIVE_ONE() # -1
123-
var zero = Decimal.ZERO() # 0
112+
# Operations respect and combine scales appropriately
113+
var a = Decimal("123.45") # Scale 2
114+
var b = Decimal("67.890") # Scale 3
115+
var addition = a + b # Scale 3 (the larger scale)
116+
var multiplication = a * b # Scale 5 (sum of scales)
117+
118+
# Very high precision values are supported
119+
var high_precision = Decimal("0.123456789012345678901234567") # 27 decimal places
124120
```
125121

126-
### 6. Handling Very Small and Large Numbers
122+
### 6. Edge Cases Handling
127123

128124
```mojo
129-
# Very small number (1 at 28th decimal place - maximum precision)
130-
var small = Decimal("0." + "0" * 27 + "1")
131-
print(small) # 0.0000000000000000000000000001
132-
133-
# Large number close to max
134-
var large = Decimal("79228162514264337593543950334") # MAX() - 1
135-
print(large) # 79228162514264337593543950334
125+
# Division by zero is detected
126+
try:
127+
var undefined = Decimal("1") / Decimal("0")
128+
print("This won't print")
129+
except:
130+
print("Division by zero detected")
136131
137-
# Calculations with extreme values
138-
var small_squared = small ** 2 # Even smaller number
132+
# Overflow is detected
133+
try:
134+
var max_val = Decimal.MAX()
135+
var overflow = max_val + Decimal("1")
136+
print("This won't print")
137+
except:
138+
print("Overflow detected")
139139
140-
# Division resulting in long repeating decimal
141-
var repeating = Decimal("1") / Decimal("3") # 0.333333... (up to max precision)
142-
print(repeating) # 0.3333333333333333333333333333
140+
# Zero handling
141+
var zero = Decimal("0")
142+
var is_zero = zero.is_zero() # True
143+
var zero_with_scale = Decimal("0.00000")
144+
var also_zero = zero_with_scale.is_zero() # True
143145
```
144146

145-
### 7. Type Conversions
147+
### 7. Working with Very Small and Large Numbers
146148

147149
```mojo
148-
var d = Decimal("123.456")
150+
# Very small number (maximum precision)
151+
var small = Decimal("0." + "0" * 27 + "1") # 0.0000000000000000000000000001
149152
150-
# String representation
151-
var str_val = String(d) # "123.456"
152-
153-
# Integer conversion (throws error if has fractional part)
154-
try:
155-
var int_val = Int(d) # Error: has non-zero fractional part
156-
print("This won't print")
157-
except:
158-
print("Cannot convert to Int with non-zero fraction")
153+
# Very large number
154+
var large = Decimal("79228162514264337593543950334") # Near maximum value
159155
160-
# Integer conversion for whole number with decimal places
161-
var whole = Decimal("100.000")
162-
var int_whole = Int(whole) # 100 (works because fractional part is zero)
156+
# Operations with extreme values
157+
var very_small_sum = small + small # 0.0000000000000000000000000002
158+
var small_product = small * small # Might result in underflow to zero due to precision limits
163159
```
164160

165-
### 8. Working with Integer Checking
161+
### 8. Negative Numbers
166162

167163
```mojo
168-
# Check if a Decimal represents an integer (even if it has decimal places)
169-
var d1 = Decimal("123") # Scale 0
170-
var d2 = Decimal("123.0") # Scale 1
171-
var d3 = Decimal("123.456") # Scale 3
172-
173-
print(d1.is_integer()) # True
174-
print(d2.is_integer()) # True - all fractional digits are 0
175-
print(d3.is_integer()) # False - has non-zero fractional digits
164+
# Creating negative numbers
165+
var neg1 = Decimal("-123.45")
166+
var neg2 = -Decimal("123.45") # Same as above
167+
168+
# Sign operations
169+
var is_negative = neg1.is_negative() # True
170+
var abs_value = abs(neg1) # 123.45
171+
var negate_again = -neg1 # 123.45
172+
173+
# Arithmetic with mixed signs
174+
var prod_neg_pos = neg1 * Decimal("2") # -246.90
175+
var prod_neg_neg = neg1 * neg2 # 15240.0025 (positive result)
176176
```
177177

178-
### 9. Error Handling
178+
### 9. Equality and Comparison
179179

180180
```mojo
181-
# Handle division by zero
182-
try:
183-
var result = Decimal("123.45") / Decimal("0")
184-
print("This won't print")
185-
except:
186-
print("Correctly caught division by zero")
181+
var a = Decimal("123.45")
182+
var b = Decimal("123.450") # Same value but different scale
187183
188-
# Handle overflow
189-
try:
190-
var max_value = Decimal.MAX()
191-
var overflow_attempt = max_value + Decimal("1")
192-
print("This won't print")
193-
except:
194-
print("Correctly caught overflow")
184+
# Equality checks the numeric value, not the representation
185+
var equal = (a == b) # True
195186
196-
# Handle invalid power operation
197-
try:
198-
var zero_neg_power = Decimal("0") ** (-1)
199-
print("This won't print")
200-
except:
201-
print("Correctly caught zero raised to negative power")
187+
# Self-comparisons
188+
var self_equal = (a == a) # Always True
189+
190+
# Zero comparisons with different scales
191+
var zero1 = Decimal("0")
192+
var zero2 = Decimal("0.000")
193+
var zeros_equal = (zero1 == zero2) # True
202194
```
203195

204-
### 10. Mathematics Module
196+
### 10. Mathematics Functions
205197

206198
```mojo
207-
from decimojo import Decimal
208-
from decimojo.mathematics import power
199+
from decimojo.mathematics import sqrt
209200
210-
# Two equivalent ways to compute powers
211-
var result1 = Decimal("2.5") ** 2
212-
var result2 = power(Decimal("2.5"), 2)
201+
# Square root
202+
var root = sqrt(Decimal("16")) # 4
213203
214-
print(String(result1) == String(result2)) # True
204+
# Rounding to specific decimal places
205+
var rounded = round(Decimal("123.456"), 2) # 123.46
215206
216-
# More complex power operations
217-
var cube = power(Decimal("2"), 3) # 8
218-
var reciprocal = power(Decimal("2"), -1) # 0.5
207+
# Absolute value (two equivalent ways)
208+
var abs1 = abs(Decimal("-123.45")) # 123.45
209+
var abs2 = abs(Decimal("-123.45")) # 123.45
219210
220-
# Can also pass a Decimal exponent (must be an integer value)
221-
var exp_as_decimal = Decimal("3")
222-
var cubed = power(Decimal("2"), exp_as_decimal) # 8
211+
# Calculating with arbitrary precision
212+
var precise_div = Decimal("1") / Decimal("7") # 0.1428571428571428571428571429
213+
var precise_sqrt = sqrt(Decimal("2")) # 1.414213562373095048801688724
223214
```
224215

225216
## Related Projects

0 commit comments

Comments
 (0)