• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Bismuth

Integer multiplication, division

17 posts in this topic

[code]int16_t a = -255;
int16_t b = 409;
int16_t c = 1000;
int16_t result = a * b / c;[/code]

result: 26
expected: -104

What the heck is going on here?
0

Share this post


Link to post
Share on other sites
?255*409
104295

int16_t is signed 16bits, and thus it ranges from -32768 to 32767
as you can see, part of your equation is out of range, and will overflow the bits
-104 is correct, as far as the computer is concerned [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

i also believe (cant remember off the top of my head) that multiplication has presedence over division
which means that the multiplication happens first Edited by Kaptein
0

Share this post


Link to post
Share on other sites
But the final result -104 does not overflow the output buffer. It's clearly in the range, so it should be assigned no problem. I'm not sure I understand what's going on here.
0

Share this post


Link to post
Share on other sites
Actually, you're running out of precision in that operation. -255 * 409 is -104,295, but [font=courier new,courier,monospace]int16_t[font=arial,helvetica,sans-serif] [/font][/font]only has 16 bits of storage, which means it can only store values in the range ?32,768 to 32,767. So what happens? Your intermediate result gets chomped down to 16 bits *before* the divide happens, and the end result is a weird value due to [url="http://en.wikipedia.org/wiki/Integer_overflow"]overflow[/url].

What should you do about it? Use a bigger data type.

[quote name='Kaptein' timestamp='1349812004' post='4988451']
i also believe (cant remember off the top of my head) that multiplication has presedence over division
which means that the multiplication happens first
[/quote]
Not quite. Multiplication, division, and modulo all have the [url="http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence"]same precedence[/url]. I can't remember if the standard guarantees left to right evaluation in this case or not though. Edited by Cornstalks
1

Share this post


Link to post
Share on other sites
limitations for a declaration may cause some problems for calculation that is what causing problem with your calculation Edited by Uzumakis
-4

Share this post


Link to post
Share on other sites
[quote name='Uzumakis' timestamp='1349812463' post='4988456']
try refreshing your compiler
[/quote]
Huh??? That makes no sense.

It's clearly due to overflow.
1

Share this post


Link to post
Share on other sites
I think you have found your answer from most of these replies. If you don't believe them then change them to int64_t and see the result
1

Share this post


Link to post
Share on other sites
[quote name='Cornstalks' timestamp='1349812336' post='4988454']
Actually, you're running out of precision in that operation. -255 * 409 is -104,295, but [font=courier new,courier,monospace]int16_t[font=arial,helvetica,sans-serif] [/font][/font]only has 16 bits of storage, which means it can only store values in the range ?32,768 to 32,767. So what happens? Your intermediate result gets chomped down to 16 bits *before* the divide happens, and the end result is a weird value due to [url="http://en.wikipedia.org/wiki/Integer_overflow"]overflow[/url].

What should you do about it? Use a bigger data type.

[/quote]

Could you please elaborate on that? What exactly is the factor that causes the calculation to be processed in 16-bit? Shouldn't the program detect that its running out of precision and automatically use a bigger (i.e. 32-bit) temporary buffer?

Which variables exactly should be increase in size?
EDIT: Is there a way to increase the temporary buffer size without changing the variable data types?
0

Share this post


Link to post
Share on other sites
[quote name='Bismuth' timestamp='1349813240' post='4988462']
[quote name='Cornstalks' timestamp='1349812336' post='4988454']
Actually, you're running out of precision in that operation. -255 * 409 is -104,295, but [font=courier new,courier,monospace]int16_t[font=arial,helvetica,sans-serif] [/font][/font]only has 16 bits of storage, which means it can only store values in the range ?32,768 to 32,767. So what happens? Your intermediate result gets chomped down to 16 bits *before* the divide happens, and the end result is a weird value due to [url="http://en.wikipedia.org/wiki/Integer_overflow"]overflow[/url].

What should you do about it? Use a bigger data type.

[/quote]

Could you please elaborate on that? What exactly is the factor that causes the calculation to be processed in 16-bit? Shouldn't the program detect that its running out of precision and automatically use a bigger (i.e. 32-bit) temporary buffer?

Which variables exactly should be increase in size?
EDIT: Is there a way to increase the temporary buffer size without changing the variable data types?
[/quote]

That's not how it works. Yes there is something that causes the calculation to be processed in 16-bit...its the fact you told it that your values are all 16 bit signed integers. when you get an overflow, instead of crashing your program. The value gets wrapped around. so when you reach the max value, it goes back to 0 and starts counting up again.

Is there a reason you chose int16_t or did you copy it from somewhere. Like I said change it to int32_t or higher and see the results Edited by !Null
1

Share this post


Link to post
Share on other sites
Thank you for explaining the situation, this clears up my doubts. I am programming an application in AVR Studio 5.1 using gcc for an Atmega328p microcontroller. Due to limited RAM on a microcontroller (2 KB) I tend to stick to 8-bit and 16-bit variables. I did some tests and it seems that increasing at least one of the vars in the equation will produce the correct result.

This does not seem to work though.
int16_t result = (uint32_t)a * b / c; // does not work

I'll do some more tests.

Regards,
Bismuth
0

Share this post


Link to post
Share on other sites
[quote name='Brother Bob' timestamp='1349813870' post='4988466']
On a side note, C++ does enforce integer promotion in this situation, so the result in C++ will be as you expected.
And on yet another side note, even when I tried to reproduce your results with VS2010 compiling the code as C code, I still get -104 so it appears it does integer promotion like C++ requires even in C.
[/quote]
Actually, C has integer promotion rules as well (I'm pretty sure C++ got them from C in the first place). The only way that the result he's getting makes sense is if int on his compiler is 16-bits in which case manually casting to plain int isn't going to help either.
1

Share this post


Link to post
Share on other sites
[quote name='Bismuth' timestamp='1349814600' post='4988472']
Thank you for explaining the situation, this clears up my doubts. I am programming an application in AVR Studio 5.1 using gcc for an Atmega328p microcontroller. Due to limited RAM on a microcontroller (2 KB) I tend to stick to 8-bit and 16-bit variables. I did some tests and it seems that increasing at least one of the vars in the equation will produce the correct result.

This does not seem to work though.
int16_t result = (uint32_t)a * b / c; // does not work

I'll do some more tests.

Regards,
Bismuth
[/quote]
Your variable a holds a negative value and you're casting it to an unsigned integer. Unsigned variables cannot hold negative values. And yes, it is technically enough to cast just a or b, because the other operands will be promoted automatically.

[quote name='SiCrane' timestamp='1349814748' post='4988473']
[quote name='Brother Bob' timestamp='1349813870' post='4988466']
On a side note, C++ does enforce integer promotion in this situation, so the result in C++ will be as you expected.
And on yet another side note, even when I tried to reproduce your results with VS2010 compiling the code as C code, I still get -104 so it appears it does integer promotion like C++ requires even in C.
[/quote]
Actually, C has integer promotion rules as well (I'm pretty sure C++ got them from C in the first place). The only way that the result he's getting makes sense is if int on his compiler is 16-bits in which case manually casting to plain int isn't going to help either.
[/quote]
I was reading through both the C and C++ specification (the drafts only, but I doubt these details change) and the two were different in that C++ explicitly mentioned integer promotion for narrow integers and C did not; otherwise the wording was more or less identical. I did not read much more than that into it, so you may very well be right. Edited by Brother Bob
1

Share this post


Link to post
Share on other sites
[quote name='Brother Bob' timestamp='1349815016' post='4988474']
Your variable a holds a negative value and you're casting it to an unsigned integer. Unsigned variables cannot hold negative values. And yes, it is technically enough to cast just a or b, because the other operands will be promoted automatically.[/quote]
Eh, sorry it was a typo. I wonder why I typed uint anyway.

int16_t cc = (int32_t)aa * bb / (pe->fade_out); // This works.
0

Share this post


Link to post
Share on other sites
To clarify this a little bit, the C standard says this about evaluating an integer expression:
[quote]
If an [font=courier new,courier,monospace]int[font=arial,helvetica,sans-serif] [/font][/font]can represent all values of the original type, the value is converted to an [font=courier new,courier,monospace]int[/font]; otherwise, it is converted to an [font=courier new,courier,monospace]unsigned int[/font]. These are called the integer promotions. All other types are unchanged by the integer promotions.
[/quote]
If I'm understanding that right, on a 32-bit system (that is, when `int` is 32-bits), then yes, you'd get the right result of -104 because each operand is implicitly promoted to an `int`. But on a system where `int` is smaller than 32-bits, (like if `int` is 16-bits), then you'll have overflow. Which is exactly why you need to either use bigger datatypes or use that cast.
2

Share this post


Link to post
Share on other sites
[quote name='Cornstalks' timestamp='1349815741' post='4988478']
To clarify this a little bit, the C standard says this about evaluating an integer expression:
[quote]
If an [font=courier new,courier,monospace]int[font=arial,helvetica,sans-serif] [/font][/font]can represent all values of the original type, the value is converted to an [font=courier new,courier,monospace]int[/font]; otherwise, it is converted to an [font=courier new,courier,monospace]unsigned int[/font]. These are called the integer promotions. All other types are unchanged by the integer promotions.
[/quote]
If I'm understanding that right, on a 32-bit system (that is, when `int` is 32-bits), then yes, you'd get the right result of -104 because each operand is implicitly promoted to an `int`. But on a system where `int` is smaller than 32-bits, (like if `int` is 16-bits), then you'll have overflow. Which is exactly why you need to either use bigger datatypes or use that cast.
[/quote]

you live, you learn :)
0

Share this post


Link to post
Share on other sites
[quote name='Arthur Souza' timestamp='1349832552' post='4988563']
Just use 32 bit integers, I dont really see why trying so hard to use 16 bits, is there a reason for it?
[/quote]
The OP explained:
[quote name='Bismuth' timestamp='1349814600' post='4988472']
I am programming an application in AVR Studio 5.1 using gcc for an Atmega328p microcontroller. Due to limited RAM on a microcontroller (2 KB) I tend to stick to 8-bit and 16-bit variables.
[/quote]

Seems like a reasonable enough thing to do with limited memory.
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0