Long multiplication: Difference between revisions
Content added Content deleted
m (→{{header|C sharp|C#}}: removed unnecessary string constants) |
(Added Visual Basic .NET, (translation of C#).) |
||
Line 5,353: | Line 5,353: | ||
0340282366920938463463374607431768211456 |
0340282366920938463463374607431768211456 |
||
</pre> |
</pre> |
||
=={{header|Visual Basic .NET}}== |
|||
{{trans|C#}}<br/> |
|||
This uses the '''decimal''' type, (which has a '''MaxValue''' of 79,228,162,514,264,337,593,543,950,335). By limiting it to '''10^28''', it allows 28 decimal digits for the ''hi'' part, and 28 decimal digits for the ''lo'' part, '''56 decimal digits''' total. A side computation of ''BigInteger'' assures that the results are accurate. |
|||
<lang vbnet>Imports System |
|||
Imports System.Console |
|||
Imports BI = System.Numerics.BigInteger |
|||
Module Module1 |
|||
Dim a As Decimal, mx As Decimal = 1E28D, hm As Decimal = 1E14D |
|||
' allows for 56 digit representation, using 28 decimal digits from each decimal |
|||
Structure bd |
|||
Public hi, lo As Decimal |
|||
End Structure |
|||
' outputs bd structure as string, optionally inserting commas |
|||
Function toStr(ByVal a As bd, ByVal Optional comma As Boolean = False) As String |
|||
Dim r As String = If(a.hi = 0, String.Format("{0:0}", a.lo), |
|||
String.Format("{0:0}{1:" & New String("0"c, 28) & "}", a.hi, a.lo)) |
|||
If Not comma Then Return r |
|||
Dim rc As String = "" |
|||
For i As Integer = r.Length - 3 To 0 Step -3 |
|||
rc = "," & r.Substring(i, 3) & rc : Next |
|||
toStr = r.Substring(0, r.Length Mod 3) & rc |
|||
toStr = toStr.Substring(If(toStr.Chars(0) = "," , 1, 0)) |
|||
End Function |
|||
' needed because Math.Pow() returns a double |
|||
Function Pow_dec(ByVal bas As Decimal, ByVal exp As UInteger) As Decimal |
|||
If exp = 0 Then Pow_dec = 1D else Pow_dec = Pow_dec(bas, exp >> 1) : _ |
|||
Pow_dec *= Pow_dec : If (exp And 1) <> 0 Then Pow_dec *= bas |
|||
End Function |
|||
Sub Main(ByVal args As String()) |
|||
For p As UInteger = 64 To 95 - 1 Step 30 ' show prescribed output and maximum power of 2 output |
|||
Dim y As bd, x As bd : a = Pow_dec(2D, p) ' init the bd variables, a = decimal value to be squared |
|||
WriteLine("The square of (2^{0}): {1,38:n0}", p, a) |
|||
x.hi = Math.Floor(a / hm) : x.lo = a Mod hm ' setup for the squaring process |
|||
Dim BS As BI = BI.Pow(CType(a, BI), 2) ' for the BigInteger checking of result |
|||
y.lo = x.lo * x.lo : y.hi = x.hi * x.hi ' square the lo and the hi parts |
|||
a = x.hi * x.lo * 2D ' calculate the middle term (mid-term) |
|||
y.hi += Math.Floor(a / hm) : y.lo += (a Mod hm) * hm ' increment hi and lo parts with high and low parts of the mid-term |
|||
While y.lo > mx : y.lo -= mx : y.hi += 1 : End While ' check for overflow, adjust both parts as needed |
|||
WriteLine(" is {0,75} (which {1} match the BigIntger computation)" & vbLf, |
|||
toStr(y, True), If(BS.ToString() = toStr(y), "does", "fails to")) |
|||
Next |
|||
End Sub |
|||
End Module</lang> |
|||
{{out}}Shown are the prescribed output and the maximum power of two that can be squared by this '''''bd''''' structure without overflowing. |
|||
<pre>The square of (2^64): 18,446,744,073,709,551,616 |
|||
is 340,282,366,920,938,463,463,374,607,431,768,211,456 (which does match the BigIntger computation) |
|||
The square of (2^94): 19,807,040,628,566,084,398,385,987,584 |
|||
is 392,318,858,461,667,547,739,736,838,950,479,151,006,397,215,279,002,157,056 (which does match the BigIntger computation)</pre> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |