-
Notifications
You must be signed in to change notification settings - Fork 1
/
float_utils.mojo
54 lines (53 loc) · 2.1 KB
/
float_utils.mojo
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
fn str_to_float(s: String) raises -> Float64:
try:
# locate decimal point
let dot_pos = s.find(".")
# grab the integer part of the number
let int_str = s[0:dot_pos]
# grab the decimal part of the number
let num_str = s[dot_pos+1:len(s)]
# set the numerator to be the integer equivalent
let numerator = atol(num_str)
# construct denom_str to be "1" + "0"s for the length of the fraction
var denom_str = String()
for _ in range(len(num_str)):
denom_str += "0"
let denominator = atol("1" + denom_str)
# school-level maths here :)
let frac = numerator / denominator
# return the number as a Float64
let result: Float64 = atol(int_str) + frac
return result
except:
print("error in str_to_float")
return 0.0
fn format_float(f: Float64, dec_places: Int) -> String:
# get input number as a string
let f_str = String(f)
# use position of the decimal point to determine the number of decimal places
let int_places = f_str.find(".")
# build a multiplier to shift the digits before the decimal point
let mult = 10 ** (dec_places + 1)
# note the use of an extra power of 10 to get the rounding digit
# use the multiplier build the integer value of the input number
let i = Float64(f * mult).cast[DType.int64]().to_int()
# get the integer value as a string
let i_str_full = String(i)
# grab the last digit to be used to adjust/leave the previous digit
let last_digit = i_str_full[len(i_str_full)-1]
# grab the last but one digit in the integer string
let prev_digit_pos = len(i_str_full) - 1
var prev_digit = i_str_full[prev_digit_pos - 1]
# if last digit is >= to 5 then we...
if ord(last_digit) >= ord(5):
# ... increment it by 1
prev_digit = chr(ord(prev_digit) + 1)
# isolate the unchanging part of integer string
var i_str_less_2 = i_str_full[0:len(i_str_full) - 2]
# grab the integer part of the output float string
let i_str_int = i_str_full[0:int_places]
# chop the integer part from the unchanging part of the number
i_str_less_2 = i_str_less_2[int_places:len(i_str_less_2)]
# build the output float string
let i_str_out = i_str_int + "." + i_str_less_2 + prev_digit
return i_str_out