Multiplying or dividing large numbers
Multiplying or dividing large numbers
Please remind me. If I do the calc Byte_Variable = 100 x 200/110 the answer should be 181, or 182 if 5/4 rounded. Does the fact that the intermediate answer of 40,000 is beyond the range of both a byte and an integer variable make it inaccurate or require me to rearrange it to say = 100/110 x 200 to keep the intermediate answer to under 255? But will then the intermediate answer of 0.91 be rounded to 1 and give 200 as the overall answer?
Similarly for integers will Integer_Variable = 1000 x 2000/-1100 work?
In summary do I only need to check that the final answer is under 255 or 32,767 respectively or do I need to worry about all the intermediate calculations getting too big and so overflowing, or too small and getting over rounded?
Similarly for integers will Integer_Variable = 1000 x 2000/-1100 work?
In summary do I only need to check that the final answer is under 255 or 32,767 respectively or do I need to worry about all the intermediate calculations getting too big and so overflowing, or too small and getting over rounded?
-
- Matrix Staff
- Posts: 9520
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
- Contact:
Re: Multiplying or dividing large numbers
From experience using integers any intermediate or final results of calculations must never exceed 32767.
If it does then results will be wrong. The simulator does not take this fact into account.
If it does then results will be wrong. The simulator does not take this fact into account.
Martin
Re: Multiplying or dividing large numbers
Also is there a simple Flowcode or C function that returns the absolute value of an integer? I.e. it ignores the minus sign?
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: Multiplying or dividing large numbers
Hello,
It depends what you want to do with the variable.
Flowcode can currently only deal with signed int variables so you could type cast the variable to unsigned but then say you wanted to print out the number on the LCD, the code to allow this assumes a signed variable.
Therefore to do this you would have to use the code customization to modify the print routine to assume an unsigned rather then a signed variable type.
It depends what you want to do with the variable.
Flowcode can currently only deal with signed int variables so you could type cast the variable to unsigned but then say you wanted to print out the number on the LCD, the code to allow this assumes a signed variable.
Therefore to do this you would have to use the code customization to modify the print routine to assume an unsigned rather then a signed variable type.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Re: Multiplying or dividing large numbers
I don’t need to put it on an LCD, at least not until lot of post-processing has been done on it so hopefully it will have forgotten that the Absolute function was used. Does this limitation only apply to the Flowcode simulator rather than in the real hardware?
So is the Absolute value created by the MOD function mentioned in the help file and how do I use it for PICs?
Volts = 11 MOD – 24 appears to work as syntax but what is it trying to do? I was hoping for a function like Excel’s
Volts = ABS (Input)
to return the value of the Input integer without the sign.
Else what is the C code to do it?
So is the Absolute value created by the MOD function mentioned in the help file and how do I use it for PICs?
Volts = 11 MOD – 24 appears to work as syntax but what is it trying to do? I was hoping for a function like Excel’s
Volts = ABS (Input)
to return the value of the Input integer without the sign.
Else what is the C code to do it?
-
- Matrix Staff
- Posts: 9520
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
- Contact:
Re: Multiplying or dividing large numbers
Attached is how I would convert signed numbers into unsigned numbers.
Its very simple and does not use C
Since it uses int, it will only convert numbers down to -32768
There maybe a simple method using C e.g using unsigned short, but that's not my area of expertise.
Hope this is what your after
Martin
Its very simple and does not use C
Since it uses int, it will only convert numbers down to -32768
There maybe a simple method using C e.g using unsigned short, but that's not my area of expertise.
Hope this is what your after
Martin
- Attachments
-
- Singned to Nonsigned1.fcf
- (5 KiB) Downloaded 486 times
Martin
- JonnyW
- Posts: 1230
- Joined: Fri Oct 29, 2010 9:13 am
- Location: Matrix Multimedia Ltd
- Has thanked: 63 times
- Been thanked: 290 times
- Contact:
Re: Multiplying or dividing large numbers
Hi there. In Flowcode v5 we have plans to support unsigned 16 and 32 bit values. It would also be nice to have abs() and sgn() functions and I'll put this on the suggestion list.
Until then, the single line:
result = value * (1 | -(value < 0))
Will do the job of abs() in a single calculation line. It will work whether the value is signed or not.
Cheers,
Jonny
Until then, the single line:
result = value * (1 | -(value < 0))
Will do the job of abs() in a single calculation line. It will work whether the value is signed or not.
Cheers,
Jonny
Re: Multiplying or dividing large numbers
Not able to read a FCF file at moment but is medelec’s code basically a Flowcode IF statement:-
IF value< 0, THEN value = - value
Whereas result = value * (1 | -(value < 0)) is presumably C code.
Which is faster on integer variables as in this case these are done within an interrupt and need to be as short as possible?
IF value< 0, THEN value = - value
Whereas result = value * (1 | -(value < 0)) is presumably C code.
Which is faster on integer variables as in this case these are done within an interrupt and need to be as short as possible?
-
- Matrix Staff
- Posts: 9520
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
- Contact:
Re: Multiplying or dividing large numbers
Im using If Value < 0 then Value = NOT Value +1echase wrote: but is medelec’s code basically a Flowcode IF statement:-
IF value< 0, THEN value = - value?
I would guess Jonnys code would be better?
Since it's all on one line
Martin
Martin
- JonnyW
- Posts: 1230
- Joined: Fri Oct 29, 2010 9:13 am
- Location: Matrix Multimedia Ltd
- Has thanked: 63 times
- Been thanked: 290 times
- Contact:
Re: Multiplying or dividing large numbers
Hi. (NOT value) + 1 is the same as -value, so thats all fine.
You would have to look at the ASM as to which is more efficient. Branches in the code tend to be the main issue on pipelined processors, though I haven't much HW or low level knowledge of the devices you are using. On many platforms, (value < 0) gets generated with a branch anyway, but optimisation of expressions may be slightly more efficient than optimisation of compound statements, such as IF.
Plus, remember that the code I posted has a multiply in it, which may or may not be slow. There are ways without this, but they look more and more ugly.
Personally I think the code I posted isn't as clear as an IF statement, but I have a BBC BASIC background so have always favoured compact lines of code. If we put support for abs() built in to Flowcode, most likely this will be done with a #define and so a single expression would most likely be used.
In short, I would go with which you find most clear and intuitive, as the speed difference shouldn't be that great between the two.
Cheers,
Jonny
You would have to look at the ASM as to which is more efficient. Branches in the code tend to be the main issue on pipelined processors, though I haven't much HW or low level knowledge of the devices you are using. On many platforms, (value < 0) gets generated with a branch anyway, but optimisation of expressions may be slightly more efficient than optimisation of compound statements, such as IF.
Plus, remember that the code I posted has a multiply in it, which may or may not be slow. There are ways without this, but they look more and more ugly.
Personally I think the code I posted isn't as clear as an IF statement, but I have a BBC BASIC background so have always favoured compact lines of code. If we put support for abs() built in to Flowcode, most likely this will be done with a #define and so a single expression would most likely be used.
In short, I would go with which you find most clear and intuitive, as the speed difference shouldn't be that great between the two.
Cheers,
Jonny
- JonnyW
- Posts: 1230
- Joined: Fri Oct 29, 2010 9:13 am
- Location: Matrix Multimedia Ltd
- Has thanked: 63 times
- Been thanked: 290 times
- Contact:
Re: Multiplying or dividing large numbers
PS:
This expression will work fine in both C and Flowcode expressions.'Whereas result = value * (1 | -(value < 0)) is presumably C code.'
Re: Multiplying or dividing large numbers
Forgive ignorance but can you explain result = value * (1 | -(value < 0)) in words? What is it doing?
| is an OR is it not?
| is an OR is it not?
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: Multiplying or dividing large numbers
Hello,
The abs() function that Jonny was talking about does the following.
"Calculates the absolute value (magnitude) of a number. The absolute value of a number is always positive."
http://processing.org/reference/abs_.html
| is indeed a logic level OR operator.
The abs() function that Jonny was talking about does the following.
"Calculates the absolute value (magnitude) of a number. The absolute value of a number is always positive."
http://processing.org/reference/abs_.html
| is indeed a logic level OR operator.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
- JonnyW
- Posts: 1230
- Joined: Fri Oct 29, 2010 9:13 am
- Location: Matrix Multimedia Ltd
- Has thanked: 63 times
- Been thanked: 290 times
- Contact:
Re: Multiplying or dividing large numbers
Yeah, this is true. In stages:
(value < 0): returns 1 if value -ve, 0 if it is not
-(value < 0): This becomes -1 if -ve, 0 if not
1 | -(value < 0): This unconditionally sets the bottom bit, so is -1 if -ve, 1 if not
If we then multiply this by our original value, we will 'flip' the sign of -ve values.
There are ways to do this without a multiply, but these get even more ugly:
result = (value ^ -(value < 0)) + (value < 0)
(value < 0): returns 1 if value -ve, 0 if it is not
-(value < 0): This becomes -1 if -ve, 0 if not
1 | -(value < 0): This unconditionally sets the bottom bit, so is -1 if -ve, 1 if not
If we then multiply this by our original value, we will 'flip' the sign of -ve values.
There are ways to do this without a multiply, but these get even more ugly:
result = (value ^ -(value < 0)) + (value < 0)
Re: Multiplying or dividing large numbers
Ben, abs() is what I want but it’s not a Flowcode function for PICs. I tried it. Does it work in C? I think that link is to C code.Benj wrote:Hello,
The abs() function that Jonny was talking about does the following.
"Calculates the absolute value (magnitude) of a number. The absolute value of a number is always positive."
http://processing.org/reference/abs_.html
.
The Help file mentions it works for one of the other processor families.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: Multiplying or dividing large numbers
Hello Echase,
Sorry the abs() function does exist for some Flowcode versions but on the PIC you will have to use Jonny's method as the compiler does not support the function directly.
Edit, I have just looked at the boostC manual and it is saying the abs() function is supported. Can you call it using a C icon?
FCV_VAR1 = abs(FCV_VAR2);
Sorry the abs() function does exist for some Flowcode versions but on the PIC you will have to use Jonny's method as the compiler does not support the function directly.
Edit, I have just looked at the boostC manual and it is saying the abs() function is supported. Can you call it using a C icon?
FCV_VAR1 = abs(FCV_VAR2);
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: Multiplying or dividing large numbers
I'd probably do something like this : result = (value < 0) ? -value : value;
http://en.wikipedia.org/wiki/%3F:#Condi ... assignment
Cheers
PS: This will need to be written in a C code box instead of the calculation box because I don't think it supports ternary operations.
http://en.wikipedia.org/wiki/%3F:#Condi ... assignment
Cheers
PS: This will need to be written in a C code box instead of the calculation box because I don't think it supports ternary operations.