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:
Top