Jeremy Leach
Senior Member
This is another version of my WordAWordBDivWordC routine, but simplified for use with any picaxe. Uses ~ 60 bytes.
It allows multiplication of a word value by a factor, without overflow, and gives an exact result expressed as a Whole and Remainder part.
For instance, the example I use in the code is converting between Knots and MPH. 1 Knot = 1.15077945 mph. So SpeedMPH = SpeedKnots * 1.15077945.
The factor value in my routine is expressed as WordB/WordC. To get the best accuracy in the results always use 65535 for WordB if the factor >1 and 65535 for WordC if the factor <1.
For example, if we know the factor needed is 1.15077945 then:
65535/WordC = 1.15077945. ie WordC = 56948
You can run this code in the sim and see the result (with serial panel active).
It allows multiplication of a word value by a factor, without overflow, and gives an exact result expressed as a Whole and Remainder part.
For instance, the example I use in the code is converting between Knots and MPH. 1 Knot = 1.15077945 mph. So SpeedMPH = SpeedKnots * 1.15077945.
The factor value in my routine is expressed as WordB/WordC. To get the best accuracy in the results always use 65535 for WordB if the factor >1 and 65535 for WordC if the factor <1.
For example, if we know the factor needed is 1.15077945 then:
65535/WordC = 1.15077945. ie WordC = 56948
You can run this code in the sim and see the result (with serial panel active).
Code:
#picaxe 08m
#rem
MULTIPLY BY FACTOR ROUTINE
==========================
DESCRIPTION
-----------
This 60 byte routine exactly multiplies a Word value by a factor, giving a whole and remainder result.
The calculations won't overflow. It assumes the result is a single word.
Result = WordA * Factor, where Factor is WordB/WordC.
To see a detailed description of how this works see my WordAWordBDivWordC routine
(this is a version for any picaxe).
TO USE
------
Set WordA, WordB and WordC.
Call MultByFactor.
The exact result is given in ResultWhole and ResultRemainder.
TIPS
----
To get the greatest accuracy, always use extreme values. i.e if a factor>1 then express it as 65535/WordC.
Or a factor < 1, express it as WordB/65535.
#endrem
'VARIABLES
'---------
Symbol WordA = w0
Symbol WordB = w1
Symbol LessThanWordC = w1
Symbol WordC = w2
Symbol ResultWhole = w3
Symbol ResultRemainder = w4
Symbol LSW = w5
Symbol TempRemainder = w5
Symbol MSW = w6
'***TEST CODE*******
'This example shows how to multiply by a factor 1.1507 (65535/56952), which is the conversion of Knots to MPH.
WordA = 201
WordB = 65535
WordC = 56952
Gosub MultByFactor
SerTxd ("ResultWhole = ",#ResultWhole," ResultRemainder = ",#ResultRemainder)
End
'*******************
MultByFactor:
'Initialise
ResultWhole = 0
ResultRemainder = 0
Do
'Calculate the most and least significant words, resulting from WordA * WordB
LSW = WordA * WordB
MSW = WordA ** WordB
'Add TermA to result
ResultWhole = -1 / WordC * MSW + ResultWhole
'Add whole part of TermC to result
ResultWhole = LSW / WordC + ResultWhole
'Calc TermC remainder value.
TempRemainder = LSW // WordC
'Calc how much ResultRemainder is currently less than WordC.
LessThanWordC = WordC - ResultRemainder
'Prepare the new Remainder value.
ResultRemainder = ResultRemainder + TempRemainder
'But adjust the Whole and Remainder values if necessary.
If TempRemainder >= LessThanWordC Then
ResultRemainder = ResultRemainder - WordC
Inc ResultWhole
EndIf
'Load WordA and WordB
WordA = - 1 // WordC + 1
WordB = MSW
Loop Until WordB = 0 'when the next iteration would give Whole and Remainder of 0.
Return
Last edited: