Arithmetic/Rational: Difference between revisions
→{{header|jq}}: add r_to_decimal
(→{{header|jq}}: add rsqrt) |
(→{{header|jq}}: add r_to_decimal) |
||
Line 1,954:
In this entry, a jq module for rational arithmetic is first
presented. It can be included or imported using jq's "include" or
"import" directives. The module includes
square roots and for converting a rational to a decimal string
or decimal string approximation,
and is sufficient for the jq solution at [[Faulhaber%27s_triangle#jq]].
Line 1,966 ⟶ 1,968:
'''Comparisons'''
*`requal`, `rgreaterthan`, `rgreaterthanOrEqual`, `rlessthan`, `rlessthanOrEqual`
'''Printing'''
* `rpp` for pretty-printing▼
* `r_to_decimal` for a decimal string representation
'''Unary'''
Line 1,973 ⟶ 1,978:
* `rinv` for unary inverse
* `rminus` for unary minus
▲* `rpp` for pretty-printing
'''Arithmetic'''
Line 2,003 ⟶ 2,007:
end;
[a,b] | rgcd;
# To take advantage of gojq's support for accurate integer division:
def idivide($j):
. as $i
| ($i % $j) as $mod
| ($i - $mod) / $j ;
# $p should be an integer or a rational
Line 2,065 ⟶ 2,075:
def rabs: r(.;1) | r(.n|length; .d|length);
def rminus:
def rminus($a; $b): radd($a; rmult(-1; $b));
Line 2,111 ⟶ 2,121:
| .root = update )
| .root ;
# Use native floats
# q.v. r_to_decimal(precision)
def r_to_decimal: .n / .d;
# Input: a Rational, {n, d} or a number
# Output: a string representation of the input as a decimal number.
# If the input is a number, it is simply converted to a string.
# Otherwise, $precision determines the number digits af precision after the decimal point,
# excluding trailing 0s. Trailing 0s are only included if they arise because of truncation.
def r_to_decimal($precision):
# Examples assuming $precision is 5:
# 0/1 => "0"
# 2/1 => "2"
# 1/2 => "0.5"
# 1/3 => "0.33333"
# 1/10 => "0.1"
# 1/1000000 => "0.00000"
# 1/100000000 => "0.00000"
if type == "number" then tostring
else . as {n: $m, d: $n}
| if $n == 0 then "denominator cannot be 0" | error
elif $n < 0 then r(-$m;-$n) | r_to_decimal($precision)
elif $m < 0 then r(-$m; $n) | r_to_decimal($precision) | .[0] |= ("-" + .)
else ($m | idivide($n) | tostring + ".") as $quotient
| {c: (($m % $n) * 10), $quotient, i: 0 }
| until (.c <= 0 or .c >= $n or .i >= $precision; .c *= 10 | .i += 1 | .quotient += "0")
| ($precision - .i) as $digits
| . + { emit: false, tail: "" }
| until (.emit;
if (.tail | length) >= $digits
then .emit = {quotient, tail}
else .q = (.c | idivide($n))
| .r = .c % $n
| .tail += (.q|tostring)
| .c = .r * 10
end
)
end
| .emit
# remove trailing zeros from tail
| .tail |= sub("0+$"; "")
| if (.tail|length) > 0
then .quotient + .tail
else (.quotient | sub("[.]$"; ""))
end
end ;
# pretty print ala Julia
|