Square root by hand: Difference between revisions

→‎{{header|Vlang}}: used vfmt on the code
m (added "non-negative" to the task's requirements.)
(→‎{{header|Vlang}}: used vfmt on the code)
Line 1,104:
import math.big
import strings
 
fn sqrt(n f64, limit int) string {
one := big.from_int(1)
ten := big.from_int(10)
twenty := big.from_int(20)
hundred := big.from_int(100)
mut n0 := n
if n0 < 0.0 {
panic("Number cannot be negative")
}
mut count := 0
for n0 != math.trunc(n0) {
n0 *= 100
count--
}
mut i := big.from_int(int(n0))
mut j := i.isqrt()
count += j.str().len
mut k := j.clone()
mut d := j.clone()
mut digits := 0
mut sb := ""
for digits < limit {
sb += d.str()
i = (i - k*d) * hundred
k = j * twenty
d = one
for big.cmp(d, ten) <= 0 {
if big.cmp((k + d)*d, i) > 0 {
d.dec()
break
}
d.inc()
}
j = j*ten + d
k = k + d
digits++
}
 
mut rootn0 := sb.trim_right("0")n
if n0 < if root0.len == 0 {
panic('Number cannot be negative')
root = "0"
}
}
if mut count >:= 0 {
for n0 != math.trunc(n0) {
root = root[0..count] + "." + root[count..]
n0 *= 100
} else if count == 0 {
count--
root = "0." + root
}
} else {
mut i := big.from_int(int(n0))
root = "0." + strings.repeat(`0`, -count) + root
mut j := i.isqrt()
}
count += j.str().len
root = root.trim_suffix(".")
mut k := j.clone()
if root.len > limit && root.contains(".") {
mut ld := rootj.after_charclone(`.`)
mut digits := 0
if l.len > limit {
mut sb := ''
root = root[0..(root.len -(l.len - limit))]
for digits < limit {
}
sb += d.str()
}
i = (i - k * d) * hundred
return root
k = j * twenty
d = one
for big.cmp(d, ten) <= 0 {
if big.cmp((k + d) * d, i) > 0 {
d.dec()
break
}
d.inc()
}
j = j * ten + d
k = k + d
digits++
}
 
mut root := sb.trim_right('0')
if root.len == 0 {
root = '0'
}
if count > 0 {
root = root[0..count] + '.' + root[count..]
} else if count == 0 {
root = '0.' + root
} else {
root = '0.' + strings.repeat(`0`, -count) + root
}
root = root.trim_suffix('.')
if root.len > limit && root.contains('.') {
l := root.after_char(`.`)
if l.len > limit {
root = root[0..(root.len - (l.len - limit))]
}
}
return root
}
 
fn main() {
numbers := [f64(2), 0.2, 10.89, 625, 0.0001]
digits := [500, 80, 8, 8, 8]
for i, n in numbers {
println("'First ${digits[i]} significant digits (at most) of the square root of $n:"')
println(sqrt(n, digits[i]))
}
}
}</lang>
{{out}}From index 310 the result of sqrt(2) is erroneous. There must beis a problem in the math.big library which uses the tiny-bignum that hat limited capabilities.
<pre style="height:72ex; overflow:scroll; white-space:pre-wrap;">First 500 significant digits (at most) of the square root of 2:
1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206057147010955997160597027453459686201472851741864088919860955232923048430871432145083976260362799525140798968725330011005640000200000003001000111402000702610001020010001611001100000200040007102100104111100076006141122001100401000138002000011012220010401152211110711200024000111111511211110000101201101111210
Anonymous user