Shop OBEX P1 Docs P2 Docs Learn Events
Multiply help please — Parallax Forums

Multiply help please

Zap-oZap-o Posts: 452
edited 2011-10-04 09:12 in Propeller 1
I am trying to multiply a number ranging from 0 to 65535 by 100_000 and its not clear why it wont calculate this. I see in the manual that the ** operator is what I need to use but how?
Pub calculate  | Temp

  Temp :=  65535 ' or any real number from 0 up to 65535  
  Temp **= 100_000
  debug (Temp)

Comments

  • Mark_TMark_T Posts: 1,981
    edited 2011-10-03 10:59
    Zap-o wrote: »
    I am trying to multiply a number ranging from 0 to 65535 by 100_000 and its not clear why it wont calculate this. I see in the manual that the ** operator is what I need to use but how?

    65535 * 100000 = 6553500000 which is beyond the range of a long variable.
  • Zap-oZap-o Posts: 452
    edited 2011-10-03 11:04
    I thought it returned the upper 64bit value?
  • Mike GreenMike Green Posts: 23,101
    edited 2011-10-03 11:07
    The ** operator gives you the upper 32 bits of a 64 bit product. What you're seeing in the debug output is this upper 32 bits. If you also display 65535 * 100_000, you'll see the lower 32 bits of the product. Is this what you want? What are you trying to do?
  • Zap-oZap-o Posts: 452
    edited 2011-10-03 11:13
    Hum, Well I want both if its possible. Here is what I am trying to do.
    Pub calculate  | Temp
    
      Temp :=  38143      ' or any real number from 0 up to 65535  
      Temp **= 100_000 
      Temp /= 13170
      Temp += -273.15 'kelvin
    
      'answer should be 262305
      debug (Temp)
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-10-03 11:43
    My umath object in the OBEX provides a multdiv method that multiplies two 32-bit unsigned numbers and retains the 64-bit product long enough to divide it by a third 32-bit operand.

    But you don't really need that. Just multiply by 10_000 and divide by 1317 using regular 32-bit Spin operations. BTW, you can't add 273.15 the way you have, since it's not an integer.

    -Phil
  • Zap-oZap-o Posts: 452
    edited 2011-10-03 11:49
    Opps! Thanks Phil I meant to put in 27315. Ill have a look at that object.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-10-03 11:56
    As I stated, you don't need that object if you reduce your multiplier and divisor by a factor of ten.

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2011-10-03 13:46
    It looks like a simple scaling problem:
    Y = X * 7.59301 - 27315
    where X ranges from 0 to 65535. Another way to approach problems of this sort will employ the ** operator in its role as a fractional multiplier. Break the problem down into its integer and fractional parts. In Prop code, it becomes,

    Y := (X * 7) + (X * 2 ** 1273479278) - 27315

    In this case the fractional part is 0.59301. The ** operator approximates that (quite accurately) as the numerator of a fraction that has a denominator of 2^32:
    X * 0.59301 = X * 2 * 0.296505 = X * 2 * (1273479278 / 4294967296)
    The division by 2^32 is implied in the ** operator.
    The reason for the factor of two is to avoid a sign bit, which would spoil it as a fractional multiply.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2011-10-04 09:12
    Or here is another way to spin it:

    Y := X * 100 ** 326117296 - 27315

    That is the same logic, but the original formula recast to make it a one-step fractional multiply by a factor less than 0.5...
    Y = X * 7.59301 - 27315
    .....= X * 100 * 0.0759301 - 27315

    where 0.0759301 = 326117296 / 2^32
Sign In or Register to comment.