Multiplying or dividing large numbers

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Multiplying or dividing large numbers

Post by echase »

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?

medelec35
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

Post by medelec35 »

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.
Martin

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: Multiplying or dividing large numbers

Post by echase »

Also is there a simple Flowcode or C function that returns the absolute value of an integer? I.e. it ignores the minus sign?

User avatar
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

Post by Benj »

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.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: Multiplying or dividing large numbers

Post by echase »

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?

medelec35
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

Post by medelec35 »

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. :cry:

Hope this is what your after :)


Martin
Attachments
Singned to Nonsigned1.fcf
(5 KiB) Downloaded 479 times
Martin

User avatar
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

Post by JonnyW »

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

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: Multiplying or dividing large numbers

Post by echase »

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?

medelec35
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

Post by medelec35 »

echase wrote: but is medelec’s code basically a Flowcode IF statement:-

IF value< 0, THEN value = - value?
Im using If Value < 0 then Value = NOT Value +1
I would guess Jonnys code would be better?
Since it's all on one line

Martin
Martin

User avatar
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

Post by JonnyW »

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

User avatar
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

Post by JonnyW »

PS:
'Whereas result = value * (1 | -(value < 0)) is presumably C code.'
This expression will work fine in both C and Flowcode expressions.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: Multiplying or dividing large numbers

Post by echase »

Forgive ignorance but can you explain result = value * (1 | -(value < 0)) in words? What is it doing?

| is an OR is it not?

User avatar
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

Post by Benj »

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.

User avatar
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

Post by JonnyW »

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)

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: Multiplying or dividing large numbers

Post by echase »

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

.
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.

The Help file mentions it works for one of the other processor families.

User avatar
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

Post by Benj »

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);

Spanish_dude
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

Post by Spanish_dude »

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.

Post Reply