View unanswered posts | View active topics It is currently Sun May 20, 2018 3:54 pm

 Page 1 of 1 [ 12 posts ]
 Print view Previous topic | Next topic
Weird division problem, 100000/1500 = -20? Right...
Author Message

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Weird division problem, 100000/1500 = -20? Right...
Hey guys,

Using the following code, I get two different results for essentially the same division:
 Code:task main() {  int _foo = 1500;  int _baz = 0;  _foo = 100000 / _foo;  _baz = 100000 / 1500;  nxtDisplayClearTextLine(3);  nxtDisplayString(3, "foo: %d", _foo);  nxtDisplayClearTextLine(4);  nxtDisplayString(4, "baz: %d", _baz);  wait1Msec(10000);}

My screen shows:
foo: -20
baz: 66

What gives? Can someone duplicate this? I am using RobotC 1.40 Public. I noticed it when I was trying to calculate the number of I2C reads I could do per second.

This is seriously odd. Ford, you're a mathematician; on what planet does 100000 / 1500 equal -20?

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]

Thu Aug 28, 2008 12:03 pm
Guru

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Re: Weird division problem, 100000/1500 = -20? Right...
 mightor wrote: Ford, you're a mathematician; on what planet does 100000 / 1500 equal -20?

Vroomvoodle 9 is famous for this.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)

Thu Aug 28, 2008 12:13 pm
Guru

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Re: Weird division problem, 100000/1500 = -20? Right...
Seriously:
I think it's an integer overflow error of a temp variable.
(maxInt=32655)
choose long instead of int and try it again

 Quote:I think it's an integer overflow error of a temp variable.

... which actually MUST NOT happen!

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)

Thu Aug 28, 2008 12:24 pm

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Re: Weird division problem, 100000/1500 = -20? Right...
Ford Prefect wrote:
Seriously:
I think it's an integer overflow error of a temp variable.
(maxInt=32655)
choose long instead of int and try it again

 Quote:I think it's an integer overflow error of a temp variable.

... which actually MUST NOT happen!

It is odd because the last time I printed out a byte with nxtDisplayString() I was getting signed longs, which I then mistook for ints. I was convinced that on a 32bit platform ints would be 32 bit long, hehe. Oh well. My bad.

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]

Thu Aug 28, 2008 2:39 pm
Guru

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Re: Weird division problem, 100000/1500 = -20? Right...
so the problem is solved now by changing int to long?

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)

Thu Aug 28, 2008 3:01 pm

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Re: Weird division problem, 100000/1500 = -20? Right...
 Ford Prefect wrote:so the problem is solved now by changing int to long?

Yeah, although it is weird that the the intermediate result is not cast to a long and then demoted back to an int. I will test this with gcc on my Linux VM. I will keep you posted!

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]

Thu Aug 28, 2008 3:04 pm

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Re: Weird division problem, 100000/1500 = -20? Right...
K, on Linux with glibc 2.7 an int is 4 bytes and a short is 2. I created this program. I used shorts because they're the same size as ints are on the NXT.
 Code:#include int main() {  short _foo = 1500;  short _baz = 0;  _foo = 100000 / _foo;  _baz = 100000 / 1500;  printf("foo: %d\n", _foo);  printf("baz: %d\n", _baz);  return 0;}

When ran it printed out 66 for both, as I expected RobotC to do. So with gcc the intermediate result *is* promoted and then demoted with some weirdness going on. So is this a bug with RobotC?

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]

Thu Aug 28, 2008 3:19 pm
Guru

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Re: Weird division problem, 100000/1500 = -20? Right...
I suppose this is working this way:
_foo = 100000 / _foo;

_foo is int,
so 1000000/_foo is passed to int:

_foo = int ((int)100000 / (int)_foo;)

It's a compiler fault, sure, this must not happen, but it happens!

I think a similar compiler fault causes my damned "-nan" at float calculations!!!

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)

Thu Aug 28, 2008 3:22 pm
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 616
Re: Weird division problem, 100000/1500 = -20? Right...
 Quote:I was convinced that on a 32bit platform ints would be 32 bit long, hehe. Oh well. My bad.

In C, the size of an "int" is independent of the hardware platform. "int" on ROBOTC are size 16 bits.

I've thought about changing the default for ROBOTC on NXT to an int size of 32 bits. Unfortunately this would have negative impacts. The ROBOTC VM (Virtual Machine) interpreter has many opcodes optimized for 16-bit ints and the compiled object files would be much larger because of use of the non-optimized formats. There are some long term enhancements to slowly remove this.

Another thing to be "cautious" of is that in C, non-float calculations are done, by default, at "int" precision unless one of the operands is a higher precision ("long"). So you could get 16-bit overflow in a calculation like:
 Code:longVariable = intVariable1 * intVariable2;

It is a bug for calculations involving long constants (i.e. outside of 16-bit range to be truncated to 16-bits. I will look into this.

Wed Sep 17, 2008 10:04 pm
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 616
Re: Weird division problem, 100000/1500 = -20? Right...
 Quote:When ran it printed out 66 for both, as I expected RobotC to do. So with gcc the intermediate result *is* promoted and then demoted with some weirdness going on. So is this a bug with RobotC?

No, it is not a bug. On the PC, the intermediate calculations are done at 32-bits which is the size of an "int" on a PC.
In ROBOTC, intermediate calculations are done with 16-bit precison of "int" used by ROBOTC.

Wed Sep 17, 2008 10:14 pm
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 616
Re: Weird division problem, 100000/1500 = -20? Right...
 Code:task main() {  int _foo = 1500;  int _baz = 0;  _foo = 100000 / _foo;  _baz = 100000 / 1500;  nxtDisplayClearTextLine(3);  nxtDisplayString(3, "foo: %d", _foo);  nxtDisplayClearTextLine(4);  nxtDisplayString(4, "baz: %d", _baz);  wait1Msec(10000);}

With ROBOTC 1.43 both "_foo" and "_baz" correctly print as value "66". I can't recall if something was fixed between 1.40 and 1.43 for this.

One minor thing to note if you look at the disassembly code (use F9 key). The compiler is smart enough to calculate the value of "_foo" at compile time.
int _foo = 1500;
int _baz = 0;
_foo = 100000 / _foo;
You'll see in the disassembly listing that there is no division and "_foo" is assigned a value of 66.
 Code:  int _foo = 1500;  int _baz = 0;  _foo = 100000 / _foo;0012: 2B0342                   _foo = 66                            _baz = 100000 / 1500;0015: 2B0442                   _baz = 66                            nxtDisplayClearTextLine(3);

I did some more testing by forcing the compiuler to generate the divide and it there is a bug where it is truncating 100000 to 16-bits and performing calculation at 16-bit precsion. THis is now fixed for the next ROBOTC release.

Wed Sep 17, 2008 10:49 pm

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Re: Weird division problem, 100000/1500 = -20? Right...
Dick,

Thanks for the explanations and insights into some of the inner workings of the compiler and VM

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]

Thu Sep 18, 2008 2:08 am
Display posts from previous:  Sort by
 Page 1 of 1 [ 12 posts ]

#### Who is online

Users browsing this forum: No registered users and 2 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ ROBOTC Applications    ROBOTC for LEGO MINDSTORMS       Third-party sensors    ROBOTC for CORTEX & PIC    ROBOTC for VEX IQ    ROBOTC for Arduino    Robot Virtual Worlds    Multi-Robot Communications    Issues and Bugs Competitions & Partners    Mini Urban Challenge    CS2N Robot Virtual Worlds Competitions       VEX Skyrise Competition 2014-2015       VEX Toss Up 2013-2014       FTC Block Party! 2013-2014    Competitions using VEX - BEST, TSA, VEX, and RoboFest!    FTC Programming    RoboCup Junior and Other ROBOT Competitions Virtual Brick Robotics Discussions    General Discussions    Project Discussions Off-Topic ROBOTC Forum & ROBOTC.net Suggestions/Feedback    ROBOTC Forums Suggestions/Comments    ROBOTC.net Suggestions/Comments       NXT Programming: Tips for Beginning with ROBOTC       VEX Programming: Tips for Beginning with ROBOTC    2013 Robotics Summer Of Learning       VEX Toss Up Programming Challenge       FTC Ring It Up! Programming Challenge    International Forums       Spanish Forums          ROBOTC for MINDSTORMS          ROBOTC for VEX       French Forums          ROBOTC pour Mindstorms          ROBOTC pour IFI VEX       Japanese Forums （日本語のフォーラム）       German Forums    2015 Spring Carnival Event    PLTW (Project Lead The Way)    Robotics Merit Badge    2014 Robotics Academy Summer of Learning