32-bit Multiplication Question - Tracy
Archiver
Posts: 46,084
I think your following solution works for me:
X=700
y = X * (X ** 7282) ' 1/9 = 7282/65536
debug dec y,cr ' prints 777
That also can be written this way?:
X = 700
Y = X + (X ** (65535/9))
DEBUG DEC Y,CR
Or if I want a better precision like 100/91 I could have like this?:
X = 700
Y = X + (X ** (100 * (65535/91)))
DEBUG DEC Y,CR
Or if I want much better precision like 1000/912 I could have like this?:
X = 700
Y = X + (X ** (1000 * (65535/915)))
DEBUG DEC Y,CR
I don't need a fraction result because Stamp don't recognize it.
Perhaps for DEBUG function that will useful.
Thanks Tracy for your help.
Cheers
--- In basicstamps@yahoogroups.com, Tracy Allen <tracy@e...> wrote:
> >ValueX = 700
> >ValueY = (ValueX * 1000) / 900
> >
> >In the real world that would give me 777.7.... But in BS2 if I
> >multiply 700 * 1000, that would exceed the 16-bit limit. I don't want
> >to multiply it by 10 or 100. I need more precision. As you can see my
> >final value that I was looking for is still 16-bit even though I can't
> >get fractions in BS2 but I'm still happy with 777.
> >
> >- Johari
>
>
> For that example, where 1000 and 900 are constants, the multiplier
is 10/9, so
> X=700
> y=X * 10/9
> debug dec y,cr
> can be done by the Stamp and prints an answer of 777.
>
> If you need one more digit of precision you can do,
> X=700
> y = (X * 10/9 *10) + (X*10//9 *10 /9)
> debug dec y/10,".",dec1 y,cr
>
> which prints 777.7
>
> Another way to do it is to use the ** operator, which works with a 32
> bit intermediate result.
>
> X=700
> y = X + (X ** 7282) ' 1/9 = 7282/65536
> debug dec y,cr ' prints 777
>
> or for more precision,
> y = X*10 + (X*2**36409) '
> debug dec y/10,".",dec1 y,cr ' prints 777.7
>
> The ** method works even when the constants are not simple like 10/9,
> for example, 1023/917 = 1.1156.
>
> If the other values are also variables, not constants, then you have
> to fall back on true double precision methods.
> more on ** and multiply by constant at
> http://www.emesystems.com/BS2math1.htm
> and more on double precision at
> http://www.emesystems.com/BS2math6.htm
>
>
> -- Tracy
X=700
y = X * (X ** 7282) ' 1/9 = 7282/65536
debug dec y,cr ' prints 777
That also can be written this way?:
X = 700
Y = X + (X ** (65535/9))
DEBUG DEC Y,CR
Or if I want a better precision like 100/91 I could have like this?:
X = 700
Y = X + (X ** (100 * (65535/91)))
DEBUG DEC Y,CR
Or if I want much better precision like 1000/912 I could have like this?:
X = 700
Y = X + (X ** (1000 * (65535/915)))
DEBUG DEC Y,CR
I don't need a fraction result because Stamp don't recognize it.
Perhaps for DEBUG function that will useful.
Thanks Tracy for your help.
Cheers
--- In basicstamps@yahoogroups.com, Tracy Allen <tracy@e...> wrote:
> >ValueX = 700
> >ValueY = (ValueX * 1000) / 900
> >
> >In the real world that would give me 777.7.... But in BS2 if I
> >multiply 700 * 1000, that would exceed the 16-bit limit. I don't want
> >to multiply it by 10 or 100. I need more precision. As you can see my
> >final value that I was looking for is still 16-bit even though I can't
> >get fractions in BS2 but I'm still happy with 777.
> >
> >- Johari
>
>
> For that example, where 1000 and 900 are constants, the multiplier
is 10/9, so
> X=700
> y=X * 10/9
> debug dec y,cr
> can be done by the Stamp and prints an answer of 777.
>
> If you need one more digit of precision you can do,
> X=700
> y = (X * 10/9 *10) + (X*10//9 *10 /9)
> debug dec y/10,".",dec1 y,cr
>
> which prints 777.7
>
> Another way to do it is to use the ** operator, which works with a 32
> bit intermediate result.
>
> X=700
> y = X + (X ** 7282) ' 1/9 = 7282/65536
> debug dec y,cr ' prints 777
>
> or for more precision,
> y = X*10 + (X*2**36409) '
> debug dec y/10,".",dec1 y,cr ' prints 777.7
>
> The ** method works even when the constants are not simple like 10/9,
> for example, 1023/917 = 1.1156.
>
> If the other values are also variables, not constants, then you have
> to fall back on true double precision methods.
> more on ** and multiply by constant at
> http://www.emesystems.com/BS2math1.htm
> and more on double precision at
> http://www.emesystems.com/BS2math6.htm
>
>
> -- Tracy
Comments
>I think your following solution works for me:
>
>X=700
> y = X * (X ** 7282) ' 1/9 = 7282/65536
^
NOTE: +, not *
> debug dec y,cr ' prints 777
>
>That also can be written this way?:
>
>X = 700
> Y = X + (X ** (65535/9))
> DEBUG DEC Y,CR
Yes, that is okay, because the fractional part is simply 1/9. If it
were a fraction like 17/155, then the equivalent formula would be
(65536 * 17 / 155), which the stamp could not compute directly. If
17/155 is a constant known in advance, it is easy, because on your
calculator the answer is 7188 (rounded up) and you can plug that in
as a constant. If the 17/155 is not known in advance, but is a
variable, there is still an way to calculate the quantity (65536 *
N/D) at run time.
' binary long division
' N/D a proper fraction, D<32768, N<32768.
' calculates N/D*65536
for J=15 to 0 ' 16 bits
N=N//D<<1 ' remainder*2
F.bit0(J)=N/D ' next bit
next
This particular workhorse formula is one that I use time and time
again in my programming.
Then,
' calculate X * (1+N/D), example (1+17/155)
X = 7000
y = X * (X ** F) ' F
debug dec y,cr ' prints 7767
>
>Or if I want a better precision like 100/91 I could have like this?:
>
>X = 700
> Y = X + (X ** (100 * (65535/91)))
> DEBUG DEC Y,CR
No, for one thing, the term in parens would come out to 72000, which
is more than the 2^16 word size. Also, it loses precision in the
divide by 91, as the fractional part is dropped. Same issues with
the next suggestion.
>
>Or if I want much better precision like 1000/912 I could have like this?:
>
>X = 700
> Y = X + (X ** (1000 * (65535/915)))
> DEBUG DEC Y,CR
>
>I don't need a fraction result because Stamp don't recognize it.
>Perhaps for DEBUG function that will useful.
>
>Thanks Tracy for your help.
>
>Cheers
>
>--- In basicstamps@yahoogroups.com, Tracy Allen <tracy@e...> wrote:
>> >ValueX = 700
>> >ValueY = (ValueX * 1000) / 900
>> >
>> >In the real world that would give me 777.7.... But in BS2 if I
>> >multiply 700 * 1000, that would exceed the 16-bit limit. I don't want
>> >to multiply it by 10 or 100. I need more precision. As you can see my
>> >final value that I was looking for is still 16-bit even though I can't
>> >get fractions in BS2 but I'm still happy with 777.
>> >
>
> > >- Johari
>>
>>
>> For that example, where 1000 and 900 are constants, the multiplier
>is 10/9, so
>> X=700
>> y=X * 10/9
>> debug dec y,cr
>> can be done by the Stamp and prints an answer of 777.
>>
>> If you need one more digit of precision you can do,
>> X=700
>> y = (X * 10/9 *10) + (X*10//9 *10 /9)
>> debug dec y/10,".",dec1 y,cr
>>
>> which prints 777.7
>>
>> Another way to do it is to use the ** operator, which works with a 32
>> bit intermediate result.
>>
>> X=700
>> y = X + (X ** 7282) ' 1/9 = 7282/65536
>> debug dec y,cr ' prints 777
>>
>> or for more precision,
>> y = X*10 + (X*2**36409) '
>> debug dec y/10,".",dec1 y,cr ' prints 777.7
>>
>> The ** method works even when the constants are not simple like 10/9,
>> for example, 1023/917 = 1.1156.
>>
>> If the other values are also variables, not constants, then you have
>> to fall back on true double precision methods.
>> more on ** and multiply by constant at
>> http://www.emesystems.com/BS2math1.htm
>> and more on double precision at
>> http://www.emesystems.com/BS2math6.htm
>>
>>
>> -- Tracy
>
>
>To UNSUBSCRIBE, just send mail to:
> basicstamps-unsubscribe@yahoogroups.com
>from the same email address that you subscribed. Text in the
>Subject and Body of the message will be ignored.
>
>
>Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Actually what I was looking for is just a fractional
multiplier/divider from 1.1 to 1.9. That gives me much room compared
to 1 to 2 which PBasic allow. My InputNum range from 100 to 3500. The
following code does work for me. With D in the range of 501 to 990, it
won't go beyond the 16 bit limit. The bonus is I can get multiplier of
1.01 to 1.09 when D is within 900 to 990. The highest InputNum I can
have is 65000. Here is the code again:
Y VAR Word
X VAR Word 'InputNum
D VAR Word
P CON 1000
MaxWord CON 65535
start:
DEBUG "Input Number: "
DEBUGIN DEC X
DEBUG CR
DEBUG "Divider: "
DEBUGIN DEC D
Y = X + (X ** (P * (MaxWord/D)))
DEBUG "Result: ", DEC Y,CR
BTW 65536 exceeds the Word capacity. In PBasic 2.5 that's illegal. I
don't know about the earlier versions.
Cheers,
- Johari
--- In basicstamps@yahoogroups.com, Tracy Allen <tracy@e...> wrote:
> Hi Johari,
>
> >I think your following solution works for me:
> >
> >X=700
> > y = X * (X ** 7282) ' 1/9 = 7282/65536
> ^
> NOTE: +, not *
>
> > debug dec y,cr ' prints 777
> >
> >That also can be written this way?:
> >
> >X = 700
> > Y = X + (X ** (65535/9))
> > DEBUG DEC Y,CR
>
>
> Yes, that is okay, because the fractional part is simply 1/9. If it
> were a fraction like 17/155, then the equivalent formula would be
> (65536 * 17 / 155), which the stamp could not compute directly. If
> 17/155 is a constant known in advance, it is easy, because on your
> calculator the answer is 7188 (rounded up) and you can plug that in
> as a constant. If the 17/155 is not known in advance, but is a
> variable, there is still an way to calculate the quantity (65536 *
> N/D) at run time.
>
> ' binary long division
> ' N/D a proper fraction, D<32768, N<32768.
> ' calculates N/D*65536
> for J=15 to 0 ' 16 bits
> N=N//D<<1 ' remainder*2
> F.bit0(J)=N/D ' next bit
> next
>
> This particular workhorse formula is one that I use time and time
> again in my programming.
>
> Then,
>
> ' calculate X * (1+N/D), example (1+17/155)
> X = 7000
> y = X * (X ** F) ' F
> debug dec y,cr ' prints 7767
>
>
>
> >
> >Or if I want a better precision like 100/91 I could have like this?:
> >
> >X = 700
> > Y = X + (X ** (100 * (65535/91)))
> > DEBUG DEC Y,CR
>
> No, for one thing, the term in parens would come out to 72000, which
> is more than the 2^16 word size. Also, it loses precision in the
> divide by 91, as the fractional part is dropped. Same issues with
> the next suggestion.
>
> >
> >Or if I want much better precision like 1000/912 I could have like
this?:
> >
> >X = 700
> > Y = X + (X ** (1000 * (65535/915)))
> > DEBUG DEC Y,CR
> >
> >I don't need a fraction result because Stamp don't recognize it.
> >Perhaps for DEBUG function that will useful.
> >
> >Thanks Tracy for your help.
> >
> >Cheers
> >
> >--- In basicstamps@yahoogroups.com, Tracy Allen <tracy@e...> wrote:
> >> >ValueX = 700
> >> >ValueY = (ValueX * 1000) / 900
> >> >
> >> >In the real world that would give me 777.7.... But in BS2 if I
> >> >multiply 700 * 1000, that would exceed the 16-bit limit. I don't
want
> >> >to multiply it by 10 or 100. I need more precision. As you can
see my
> >> >final value that I was looking for is still 16-bit even though I
can't
> >> >get fractions in BS2 but I'm still happy with 777.
> >> >
> >
> > > >- Johari
> >>
> >>
> >> For that example, where 1000 and 900 are constants, the multiplier
> >is 10/9, so
> >> X=700
> >> y=X * 10/9
> >> debug dec y,cr
> >> can be done by the Stamp and prints an answer of 777.
> >>
> >> If you need one more digit of precision you can do,
> >> X=700
> >> y = (X * 10/9 *10) + (X*10//9 *10 /9)
> >> debug dec y/10,".",dec1 y,cr
> >>
> >> which prints 777.7
> >>
> >> Another way to do it is to use the ** operator, which works with a 32
> >> bit intermediate result.
> >>
> >> X=700
> >> y = X + (X ** 7282) ' 1/9 = 7282/65536
> >> debug dec y,cr ' prints 777
> >>
> >> or for more precision,
> >> y = X*10 + (X*2**36409) '
> >> debug dec y/10,".",dec1 y,cr ' prints 777.7
> >>
> >> The ** method works even when the constants are not simple like 10/9,
> >> for example, 1023/917 = 1.1156.
> >>
> >> If the other values are also variables, not constants, then you have
> >> to fall back on true double precision methods.
> >> more on ** and multiply by constant at
> >> http://www.emesystems.com/BS2math1.htm
> >> and more on double precision at
> >> http://www.emesystems.com/BS2math6.htm
> >>
> >>
> >> -- Tracy
> >
> >
> >To UNSUBSCRIBE, just send mail to:
> > basicstamps-unsubscribe@yahoogroups.com
> >from the same email address that you subscribed. Text in the
> >Subject and Body of the message will be ignored.
> >
> >
> >Your use of Yahoo! Groups is subject to
http://docs.yahoo.com/info/terms/