Jump to content

Arithmetic/Rational: Difference between revisions

→‎{{header|jq}}: simpler r_to_decimal/1
(→‎{{header|jq}}: add r_to_decimal)
(→‎{{header|jq}}: simpler r_to_decimal/1)
Line 1,998:
in the case of requal/2.
 
'''module {"name": "Rational"};'''
<lang jq># a and b are assumed to be non-zero integers
def gcd(a; b):
Line 2,126:
def r_to_decimal: .n / .d;
 
# Input: a Rational, or {n, d} in general, or aan numberinteger.
# 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 of digits af precision after the decimal point,
# obtained by truncating, but trailing 0s are omitted.
# excluding trailing 0s. Trailing 0s are only included if they arise because of truncation.
# Examples assuming $precisiondigits is 5:
def r_to_decimal($precision):
# -0//1 => "0"
# Examples assuming $precision is 5:
# 02//1 => "02"
# 2/1//2 => "20.5"
# 1/2/3 => "0.533333"
# 17/3/9 => "0.3333377777"
# 1/10/100 => "0.101"
# -1/1000000/10 => "-0.000001"
# 1/100000000/1000000 => "0.00000"
def r_to_decimal($precisiondigits):
if type == "number" then tostring
if .n == 0 # captures the annoying case of -0
else . as {n: $m, d: $n}
then "0"
| if $n == 0 then "denominator cannot be 0" | error
elif $ntype <== 0"number" then r(-$m;-$n) | r_to_decimal($precision)tostring
elif $m.d < 0 then r({n: -$m; $.n), d: -.d}| r_to_decimal($precision) | .[0] |= ("-" + .digits)
elif .n < 0
else ($m | idivide($n) | tostring + ".") as $quotient
then "-" + ((.n = -.n) | r_to_decimal($digits))
| {c: (($m % $n) * 10), $quotient, i: 0 }
else (10|power($digits)) as $p
| until (.c <= 0 or .c >= $n or .i >= $precision; .c *= 10 | .i += 1 | .quotient += "0")
| ($precision - .i)d as $digitsd
| .if +$d {== emit:1 false,then tail: "" }.n|tostring
else ($mp * .n | idivide($nd) | tostring + ".") as $quotientn
| until (.emit;
if| (.tail $n| length) >=as $digitsnlength
| (if $nlength > $digits then $n[0:$nlength-$digits] + "." + $n[$nlength-$digits:]
then .emit = {quotient, tail}
else "0.q" =+ (.c"0"*($digits |- idivide($nnlength) + $n)
end) | .r = .c % sub("0+$n";"")
end
| .tail += (.q|tostring)
end ;
| .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
2,454

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.