Multiply by a factor, precisely

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).

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: