Long multiplication: Difference between revisions
Content added Content deleted
No edit summary |
(→{{header|Tcl}}: Task really calls for manual multiplication, so do it...) |
||
Line 567: | Line 567: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{works with|Tcl|8.5}} |
{{works with|Tcl|8.5}}<br> |
||
Tcl 8.5 supports arbitrary-precision integers, which improves math operations on large integers. |
Tcl 8.5 supports arbitrary-precision integers, which improves math operations on large integers. It is easy to define our own by following rules for long multiplication; we can then check this against the built-in's result: |
||
<lang tcl>package require Tcl 8.5 |
<lang tcl>package require Tcl 8.5 |
||
proc longmult {x y} { |
|||
set digits [lreverse [split $x ""]] |
|||
set result {0} |
|||
set j -2 |
|||
foreach m [lreverse [split $y ""]] { |
|||
set c 0 |
|||
set i [incr j] |
|||
foreach d $digits { |
|||
set v [lindex $result [incr i]] |
|||
if {$v eq ""} { |
|||
lappend result 0 |
|||
set v 0 |
|||
} |
|||
regexp (.)(.)$ 0[expr {$v + $c + $d*$m}] -> c v |
|||
lset result $i $v |
|||
} |
|||
lappend result $c |
|||
} |
|||
# Reconvert digit list into a decimal number |
|||
set result [string trimleft [join [lreverse $result] ""] 0] |
|||
if {$result == ""} then {return 0} else {return $result} |
|||
} |
|||
puts [set n [expr {2**64}]] |
puts [set n [expr {2**64}]] |
||
puts [longmult $n $n] |
|||
puts [expr {$n * $n}]</lang> |
puts [expr {$n * $n}]</lang> |
||
outputs |
outputs |
||
<pre>18446744073709551616 |
<pre>18446744073709551616 |
||
340282366920938463463374607431768211456 |
|||
340282366920938463463374607431768211456</pre> |
340282366920938463463374607431768211456</pre> |