The first one makes sense to me. As you are doing fixed point math.So b divided by anything greater than the value of b will give you a value of 0 which multiplied by anything will give you a value of 0.

I have not taken time yet to figure out your second half. But I am pretty sure it has to do with what number system each calculation is being done at and if that overflows the registers. It also does not help one of your variables is signed and the other is unsigned. If it were me I would probably try casting the values while doing the math. Maybe something like:( ((int32)a)*((int32)b)/1000000L

This is probably overkill. Also I show your divide constant as a long. I had to do some of this stuff when I converted the phoenix code that runs in Basic on a Basic Atom Pro to C as the basic did all of it's math as 32 bits...

Welcome to all that is bad, (or good if you understand whats going on), about C/C++ and most other languages.This entire thread has nothing to do with WebbotLib or rprintf - its ALL about how C works.

The WebbotLib 'rprintf' command is identical to the standard C 'printf' routine in that it takes a variable number of parameters. The first parameter is the 'format string' showing how to display the answer. The remaining parameters are the values to be used in the format string.The format string can contain things like:-%s - to display a string%d - to show a signed 16 bit (int16_t) number%u - to show an unsigned 16 bit (uint16_t) number%ld - to show a signed 32 bit (int32_t) number

Given the format strings you have used then the additional parameters should contain data which matches the data type from the format string.

You know this. The C language syntax document knows this. But unfortunately all C compilers have no idea that this is the case. As far as the compiler is concerned the format string is just that - its just a string. So the compiler has no way to check the datatypes in the format string against the other parameters which represent the values to be substituted.

As a simple example - the following is totally allowed by the compiler:int16_t num = 65;rprintf("Text =%s\n", num);This will compile without any errors and you may expect it to output 'Text =65' but you would be very wrong.It will output complete junk. The format string contains a %s meaning it should be replaced by the string given in the arguments. But the only other argument is 'num' which is an integer number and not a string. Since 65 is the ASCII value for 'A' then it will probably, if you are lucky, show 'Text =A' but, if you are unlucky' then this may be proceeded by all sorts of gubbins.

The format string shows that it expects:- an int16_t- another int16_t- an int32_tBut the actual parameters passed in are:- 'a' an int16_t- 'b' an uint32_t- 'a*(b/1000000)' hard to say but since every element is an integer - the largest being a 32 bit number - then will probably be an int32_t

The result is that it prints out this data:-599 17897 4which Admin 'thinks' is wrong. Lets go through it by comparing the info shown above for what the 'format string' has been asked to do vs the actual parameter it has been passed to use.1. Format string has '%d' ie an int16_t and it has been passed 'a' which is an int16_t and so outputs the correct answers '-599'2. Format string has '%d' ie an int16_t and it has been passed 'b' which is an uint32_t. So now it will start outputing the wrong data.3. Since the previous entry has been messed up then all remaining parameters will also be messed up.

Thats why the third value comes out as 4 rather than 0 - its messed up because of the mismatch on the previous values format string vs the data its been given.

So one way to fix it is force the parameters to match the types specified in the format string by using a cast. ierprintf("%d %d %ld\n",(int16_t)a, (int16_t)b, (int32_t)(a* (b/1000000) ) );

This will now output the last value as '0' rather than the erroneous '4'.Admin tried to do this by having this as a seperate line of code which also outputs '0':-

rprintfFloat(8,a*(b/1000000));The next question admin has is why does that last value come out as 0?Well a=-599 and b=17897.These are both whole numbers (integers).The first step is (b/1000000) where b is an integer and 1000000 is an integer so the result (0.017897) as an integer is 0. Multiply by 'a' and the answer is still 0. Since the rprintfFloat function expects a 'float' value then it will convert the value to a 'float' before printing. ie it converts the integer value '0' to the float value '0.000000'.

rprintfFloat(8,(a*b)/1000000f);By adding the 'f' at the end then we are saying its a floating point number.

So now we have (int * int) / (float) and so the answer will be a float rather than an integera * b = -10,720,303div by 1000000.0 = -10.720303Converted to a float is -10.720303So this will output -10.720303

Before I continue, I just want to say that I simplified my example in this thread to make it easy for anyone to understand and help debug it. There were quite complex calculations going on all over the place, with many variables dependent on each other. It was really difficult to figure out if the variables were saving data wrong, the calculations were wrong, or the rprintf was just outputting the data wrong . . . in the end, it turned out to be all three, making debugging a huge pain

Now knowing the root problems, its obvious I oversimplified the example here a bit too much.

Quote

3. Since the previous entry has been messed up then all remaining parameters will also be messed up.

That explains it! I wasn't sure how rprintf works . . . I assumed only 'messed up' values would get messed up, and not anything following. From now on I'll just break up my rprintf statements to help narrow done the mistakes.

Quote

So one way to fix it is force the parameters to match the types specified in the format string by using a cast. ierprintf("%d %d %ld\n",(int16_t)a, (int16_t)b, (int32_t)(a* (b/1000000) ) );

In the end, this is almost exactly what I ended up doing. This whole experience was a much needed lesson in properly casting variables . . .

Webbot, in your WebbotLib manual, can you state which variable type each %d,%ld,%s, etc. expects in the rprintf section? (page 93 of v1.26) I think it'll help others avoid this issue.

Lol, I think we all knew you simplified the example . Yeah printf was kind of a duh moment for me too. Should have realized it myself before my response but I was at work with my mind on other things . But its always good to break down complex calculations and outputs into as many steps as possible to weed out exactly where the problem lies.

Logged

"Never regret thy fall, O Icarus of the fearless flight For the greatest tragedy of them allIs never to feel the burning light."

Most sensors are grouped into a folder: eg Sensors/Distance.That folder has a file of the format _xxxxx_common.h ie _distance_common.h Open that up and you will see the #define for the DISTANCE_TYPE

equally ENCODER_TYPE can be found in Sensors/Encoder/_encoder_common.h

etc

Of course if you are using a decent IDE, like Eclipse, you can just highlight the datatype and press F3 and it will open up the correct file at the correct line number of where it is defined. Shame that AVRStudio is just a text editor. But hey ho.