Shop OBEX P1 Docs P2 Docs Learn Events
How to map a number range to another number range in spin? — Parallax Forums

How to map a number range to another number range in spin?

kf4ixmkf4ixm Posts: 529
edited 2011-03-13 15:57 in Propeller 1
i've been trying to wrap my head around this all morning and for the life of me, can't figure out how to do this. what i want to do is take a number from 0 to 4096 and map that to a value between 1000 and 2000. I'm pretty sure im just missing something obvious, but thought that maybe someone could show me a spin example to do this. Thanks in advance!

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-03-12 08:49
    The size of your domain is 4096; your range, 1000 (i.e. 2000 - 1000). So you need to multiply by 1000, then divide by 4096 (i.e. shift right by 12). Finally, you have an offset of 1000, so add that:
    new := (old * 1000) >> 12 + 1000
    

    -Phil
  • Martin_HMartin_H Posts: 4,051
    edited 2011-03-12 08:56
    Phil, I was about to reply, but my solution had / 4096 in it. I like your solution much better.

    Question: In the old days bit shifting was much faster than division, but on many modern CPU's the ALU's can divide quickly. Is bit shifting faster on the Propeller?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-03-12 08:56
    x := ((y * 1000) / 4096) + 1000

    EDIT: Phil beat me to it, and >> 12 takes less compute than / 4096
  • kf4ixmkf4ixm Posts: 529
    edited 2011-03-12 09:03
    WOW, thanks for the quick replies! i really appreciate it. i will try these out and see what i come up with.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-03-12 09:24
    Martin_H,
    The Propeller does multiplication and division by subroutine (about 5us). It's relatively fast in Spin because of the general overhead in interpreting Spin code. All shifting is done in one instruction time (50ns at 80MHz) because the Propeller has what's called a "barrel shifter" which can do any size shift of any kind in one cycle.
  • Heater.Heater. Posts: 21,230
    edited 2011-03-12 09:49
    Except replacing all the power of two divides and multiplies in my FFT routine with shifts made no appreciable difference to over all execution speed.
  • localrogerlocalroger Posts: 3,452
    edited 2011-03-12 14:36
    You can do this in one operation with the ** operator. ** returns the high 32 bits of a 32x32 bit multiplication. You can regard it as x ** y == x * y / 2^32 and it's great for using integer math to multiply by a fraction less than 1. In your case, you want x * y * 1000 / 4096 (plus 1000 of course, but that's kind of obvious). Form your y constant as 1000 / 4096 * 2^32 = 1_048_576_000. So to scale from 0-4096 to 1000-2000 you would use r = x ** 1_048_576_000 + 1000.
  • Martin_HMartin_H Posts: 4,051
    edited 2011-03-12 17:53
    @Mike Green, thanks for the explanation. I think I'm going to have to dig into PASM because it sounds like the instruction set will be a blast from the past.

    @localroger, that is really good to know, multiplying to divide!
  • kwinnkwinn Posts: 8,697
    edited 2011-03-12 20:41
    Martin_H wrote: »
    @Mike Green, thanks for the explanation. I think I'm going to have to dig into PASM because it sounds like the instruction set will be a blast from the past.

    @localroger, that is really good to know, multiplying to divide!

    The PASM instruction set IS a "blast from the past". It is also a "chunk of the present and future" since the same basic arithmetic and logic functions are used in current computers, and will almost certainly be in future ones as well.
  • localrogerlocalroger Posts: 3,452
    edited 2011-03-13 15:57
    The PASM instruction set is actually pretty rich; most CPU's going back to the very beginning have fewer instructions (you don't get things like MAX, MIN, MUXC, etc.) but more addressing modes (even the 8080 and 6502 do indirect addressing without resorting to self-modifying code). PASM also has a few gotchas; in particular the flags don't behave the same on shifts as they do on most CPU's. But PASM is very elegant and a lot of fun once you "get" the philosophy behind it. The ability to complement every single instruction in your program with modifiers like wc, wz, and nr is also unheard of in other architectures. Basically, by accepting a tiny 9-bit address space, Chip opened up the 32-bit program word to include both source and destination addresses and all these powerful options; in CPU's with larger memory spaces, those options require more words of source code making the program bigger and slower.
Sign In or Register to comment.