473,387 Members | 1,683 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

integer division

hi,
i'm new to MS Visual Studio and C++ but not to C programming in general. i'm
trying to divide two integers and get their actual quotient (eg 5/3 =
1.666667 etc). i thought i had type cast correctly, but please let me know,
because it appears to be rounding off. my code follows. Thanks!

void DrawLine(GLint x1, GLint y1, GLint x2, GLint y2)

{
int i, pk, dy, dx, yc, xc, inc, temp;
float m;
/*
x1 = 100;
y1 = 200;
x2 = 110;
y2 = 206;
*/

if((x1 >= x2) && (y1 >= y2)) {
temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
}

dy = y2 - y1;
dx = x2 - x1;
if (dx != 0) m = (float)(dy/dx);
else m = -999;

// Debugging info
printf("\nDrawLine called!\n");
printf("x1 = %d\n", x1);
printf("y1 = %d\n", y1);
printf("x2 = %d\n", x2);
printf("y2 = %d\n", y2);
printf("dx = %d\n", dx);
printf("dy = %d\n", dy);
if (dx != 0) printf("dy/dx = %d\n", dy/dx);
printf("m = %.2f\n", m);
}
OUTPUT:


DrawLine called!
x1 = 286
y1 = 204
x2 = 309
y2 = 187
dx = 23
dy = -17
dy/dx = 0
m = 0.00
Nov 14 '05 #1
9 17207
Darius Fatakia wrote:
hi,
i'm new to MS Visual Studio and C++ but not to C programming in
general. i'm trying to divide two integers and get their actual
quotient (eg 5/3 =
1.666667 etc). i thought i had type cast correctly, but please let me
know, because it appears to be rounding off. my code follows. Thanks!

void DrawLine(GLint x1, GLint y1, GLint x2, GLint y2)

{
int i, pk, dy, dx, yc, xc, inc, temp;
float m;
/*
x1 = 100;
y1 = 200;
x2 = 110;
y2 = 206;
*/

if((x1 >= x2) && (y1 >= y2)) {
temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
}

dy = y2 - y1;
dx = x2 - x1;
if (dx != 0) m = (float)(dy/dx);


One solution would be:

if (dx != 0) m = (float)dy/(float)dx;

Nov 14 '05 #2
You are typecasting the result of the INTEGER
arithmetic (dy/dx) to a FLOAT. You should rather
typecast both dy and dx to a FLOAT (or double)
in the expression.

e.g.

m = ( float(dy)/float(dx) );

or declare float( or double) variables to which you
assign the integer values of dy and dx.


Darius Fatakia wrote:
hi,
i'm new to MS Visual Studio and C++ but not to C programming in general. i'm
trying to divide two integers and get their actual quotient (eg 5/3 =
1.666667 etc). i thought i had type cast correctly, but please let me know,
because it appears to be rounding off. my code follows. Thanks!

void DrawLine(GLint x1, GLint y1, GLint x2, GLint y2)

{
int i, pk, dy, dx, yc, xc, inc, temp;
float m;
/*
x1 = 100;
y1 = 200;
x2 = 110;
y2 = 206;
*/

if((x1 >= x2) && (y1 >= y2)) {
temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
}

dy = y2 - y1;
dx = x2 - x1;
if (dx != 0) m = (float)(dy/dx);
else m = -999;

// Debugging info
printf("\nDrawLine called!\n");
printf("x1 = %d\n", x1);
printf("y1 = %d\n", y1);
printf("x2 = %d\n", x2);
printf("y2 = %d\n", y2);
printf("dx = %d\n", dx);
printf("dy = %d\n", dy);
if (dx != 0) printf("dy/dx = %d\n", dy/dx);
printf("m = %.2f\n", m);
}

OUTPUT:

DrawLine called!
x1 = 286
y1 = 204
x2 = 309
y2 = 187
dx = 23
dy = -17
dy/dx = 0
m = 0.00


--
"It is impossible to make anything foolproof because fools are so
ingenious" - A. Bloch

Nov 14 '05 #3
On Tue, 27 Jan 2004 17:24:51 -0800, "Darius Fatakia"
<da************@yahoo.com> wrote in comp.lang.c:
hi,
i'm new to MS Visual Studio and C++ but not to C programming in general. i'm
trying to divide two integers and get their actual quotient (eg 5/3 =
1.666667 etc). i thought i had type cast correctly, but please let me know,
because it appears to be rounding off. my code follows. Thanks! void DrawLine(GLint x1, GLint y1, GLint x2, GLint y2)

{
int i, pk, dy, dx, yc, xc, inc, temp;
float m;
[snip]
if (dx != 0) m = (float)(dy/dx);


The type of an expression in C depends solely on the type of its
arguments, and is not influenced in any way by what you might do with
the result of the expression.

dy and dx are ints, so dx/dy is an int division expression which
produces an int result, that is truncates the quotient to an int.

The fact that you cast the result afterwards does not change this.
The int result, with no fractional part, will be converted to float
even without the cast, simply by assigning it to the float object m.

To force the expression to be performed as a float operation, one or
both of the operands must be a float. So you need to do one of:

if (dx != 0) m = ((float)dy/dx);

if (dx != 0) m = (dy/(float)dx);

if (dx != 0) m = ((float)dy/(float)dx);

If you convert either of the operands to float by a cast, the compiler
must automatically promote the other float, perform a float divide,
and produce a float result.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #4
Jack Klein <ja*******@spamcop.net> wrote in message news:<sc********************************@4ax.com>. ..
if (dx != 0) m = (float)(dy/dx);


dy and dx are ints, so dx/dy is an int division expression which
produces an int result, that is truncates the quotient to an int.


This answer is, of course, correct, but I want to seize on it as
a simple example of the advantages of *Low-level* (WYSIWYG) languages.

One needn't be a C expert to deduce Mr. Klein's correct answer.
Just examining the parentheses one sees (dy/dx) or (5/3)
"should" be evaluated before the (float) part. Since (5/3) is 1,
(float)(5/3) is (float)(1) is 1.0000, not 1.6667. In this simple
case, if you understand parentheses you understand C.

Now perhaps a "friendly" high-level language would remember where
the (1) came from and evaluate (float)(1) as 1.6667. Would you like
that? Not I, but I gather some people find such "friendly" features
.... er, friendly!

C++ will also evaluate (float)(5/3) as 1.0000 but that's only because
the friendly C++ designers haven't gotten around to letting parentheses
be overloadable :-)

In slightly less egregious cases, C++ prides itself on doing the friendly
thing rather than the WYSIWYG thing.

That's what the debate is about between C++ fans and C fans.
The C fans aren't too lazy to construct operator inheritance mazes;
we just put more of a premium on transparent clarity.

James
Nov 14 '05 #5
ark

"Jack Klein" <ja*******@spamcop.net> wrote in message
news:sc********************************@4ax.com...
On Tue, 27 Jan 2004 17:24:51 -0800, "Darius Fatakia"
<da************@yahoo.com> wrote in comp.lang.c:
<snip>
To force the expression to be performed as a float operation, one or
both of the operands must be a float. So you need to do one of:

if (dx != 0) m = ((float)dy/dx);

if (dx != 0) m = (dy/(float)dx);

if (dx != 0) m = ((float)dy/(float)dx);

If you convert either of the operands to float by a cast, the compiler
must automatically promote the other float, perform a float divide,
and produce a float result.

<snip>
IMHO, compilers are not created equal, and while these three options are
mathematically equivalent, a compiler may have a better chance of optimizing
the 1st variant (essentially, by dividing integer mantissa of the
not-necessarily-fully-formed float). It may be more important for targets
without a hardware FPU or even a division instruction. For the same reason,
one may want to keep the divisor in an unsigned type when possible.
As a separate note, I believe there are 100% integral line drawing
algorithms out there (cannot give references now, try search).
Ark
Nov 14 '05 #6
On Wed, 28 Jan 2004 07:22:22 GMT, "ark" <ar****@comcast.net> wrote in
comp.lang.c:

"Jack Klein" <ja*******@spamcop.net> wrote in message
news:sc********************************@4ax.com...
On Tue, 27 Jan 2004 17:24:51 -0800, "Darius Fatakia"
<da************@yahoo.com> wrote in comp.lang.c:

<snip>

To force the expression to be performed as a float operation, one or
both of the operands must be a float. So you need to do one of:

if (dx != 0) m = ((float)dy/dx);

if (dx != 0) m = (dy/(float)dx);

if (dx != 0) m = ((float)dy/(float)dx);

If you convert either of the operands to float by a cast, the compiler
must automatically promote the other float, perform a float divide,
and produce a float result.

<snip>
IMHO, compilers are not created equal, and while these three options are
mathematically equivalent, a compiler may have a better chance of optimizing
the 1st variant (essentially, by dividing integer mantissa of the
not-necessarily-fully-formed float). It may be more important for targets
without a hardware FPU or even a division instruction. For the same reason,
one may want to keep the divisor in an unsigned type when possible.
As a separate note, I believe there are 100% integral line drawing
algorithms out there (cannot give references now, try search).
Ark


Optimization is not a language issue, and whether certain compilers
might generate more efficient code for one of the expressions above is
irrelevant in this group. What might be the "most efficient" on one
compiler might be least on another, or even on the same compiler with
a different set of options.

As for the algorithm you are referring to, a Google search on "Integer
Bresenham Algorithm" should turn up the references. Twenty years ago
I used it to generate pixel coordinates for displaying machine tool
contours on a Tecmar Grahpics Master (this was before such things as
EGA and VGA video) with an 8088.

There was no Internet or search engines in those days, so I invented
my own integer only algorithm similar to Breshenham's for circles and
circular arcs.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #7
ark

"Jack Klein" <ja*******@spamcop.net> wrote in message
news:io********************************@4ax.com...
On Wed, 28 Jan 2004 07:22:22 GMT, "ark" <ar****@comcast.net> wrote in
comp.lang.c: <snip> Optimization is not a language issue, and whether certain compilers
might generate more efficient code for one of the expressions above is
irrelevant in this group. What might be the "most efficient" on one
compiler might be least on another, or even on the same compiler with
a different set of options.

<snip>

Languages are made to accomplish certain tasks, not just for syntactic fun.
For instance,
unsigned x; ..., x/=2;
is equivalent to x>>=1;
whereas
int x; ..., x/=2;
is roughly equivalent to
if(x<0) x+=1; x>>=1;
or about 200% overhead plus possible pipeline break, if any.
So I am not convinced that efficiency is totally off topic here...
- Ark
Nov 14 '05 #8
Nick Landsberg <hu*****@att.net> wrote:
You are typecasting the result of the INTEGER
arithmetic (dy/dx) to a FLOAT. You should rather
typecast both dy and dx to a FLOAT (or double)
in the expression.

e.g.

m = ( float(dy)/float(dx) );


That would be C++, but in C typecasts must be written (float)dx ...
Also Note that it should be enough to cast either of the operands
to float (or even better double) to force the calculation to be done
in float. The other operand will be magically converted according to
usual arithmetic conversions.

--
Z (Zo**********@daimlerchrysler.com)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
Nov 14 '05 #9
"ark" <ar****@comcast.net> wrote:
"Jack Klein" <ja*******@spamcop.net> wrote in message
news:io********************************@4ax.com...
Optimization is not a language issue, and whether certain compilers
might generate more efficient code for one of the expressions above is
irrelevant in this group. What might be the "most efficient" on one
compiler might be least on another, or even on the same compiler with
a different set of options.
Languages are made to accomplish certain tasks, not just for syntactic fun.


True, but the language specification cannot rule over everything. And
the topic of this newsgroup is ISO C, not C-as-it-happens-to-run-on-
your-system, because tomorrow you may have a new computer which may make
these micro-optimisations completely unreliable.
For instance,
unsigned x; ..., x/=2;
is equivalent to x>>=1;
True, because it is guaranteed by the Standard; but you do not know
which of them will turn out to be more efficient on any particular
system until you measure it, and those measurements will not be valid
for most other systems. And in fact, many good compilers will compile
these two expressions to the very same machine code.
whereas
int x; ..., x/=2;
is roughly equivalent to
if(x<0) x+=1; x>>=1;
Wrong, wrong, utterly wrong.
For positive values and zero, the same equivalence as for unsigned int
holds. For negative values, however, the result of the shift is
implementation-defined. It is certainly possible that _your_
implementation happens to define it as the above code; but this is by no
means guaranteed, and anyone relying on it is setting himself up for a
surprise.
The division, OTOH, is perfectly defined for all values. So the division
and the shift-complex aren't equivalent at all, not even roughly.
or about 200% overhead plus possible pipeline break, if any.
You do not know any of that. You do not know that the +=1 gives you a
200% overhead. You do not know that the target computer even _has_ a
pipeline, let alone that this code could break it. You do not know that
the end result is the same. And finally, you do not know how efficiently
the target system implements signed integral divisions and shifts, so
you have no idea which of the two alternatives actually _is_ the most
efficient until you measure it.
So I am not convinced that efficiency is totally off topic here...


It is. It is totally system-dependent, and therefore totally off-topic.

Richard
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Matthew Wilson | last post by:
Hi- I just discovered this: >>> -1 // 12 -1 >>> 1 // 12 0 >>>
2
by: Michael Cornelius | last post by:
As an old C programmer, I'm surprised by some results I'm getting with integer division. For example: >>> -1/1000 -1 >>> -9/2 -5 I expect the results of these expressions to be 0 and -4,...
19
by: Imbaud Pierre | last post by:
integer division and modulo gives different results in c and python, when negative numbers are involved. take gdb as a widely available c interpreter print -2 /3 0 for c, -1 for python. more...
24
by: Teis Draiby | last post by:
In .NET, can I be sure that the result of a division between two integers always is truncated rather that rounded to nearest? Example: 99 / 50 = 1 regards, Teis
2
by: Darius Fatakia | last post by:
hi, i'm new to MS Visual Studio and C++ but not to C programming in general. i'm trying to divide two integers and get their actual quotient (eg 5/3 = 1.666667 etc). i thought i had type cast...
3
by: Sidney Cadot | last post by:
Hi all, As I understand it, the rounding direction of signed integer division in C is unspecified in C89/C94, and specified to be 'towards-zero' in C99. I need division 'towards -infinity'...
6
by: J.Marsch | last post by:
Suppose that I have an integer division problem, but I want the answer was a float. What's the cleanest syntax for that? Example: In this code, the variable z ends up == 0. And that is...
2
by: Ben | last post by:
Hi, I have an interesting example from my debugger. I have 2 variables: sourcewidthnet and targetwidthnet. Notice the results in the debugger. I'm going to be forced to use the int function of the...
9
by: PengYu.UT | last post by:
Hi, The usually integer division will round the result to the biggest integet smaller than the float version division.For example, 10/3 = 3. I'm wondering if there is any easy way to round it...
1
by: Marge | last post by:
Create a java program that performs integer division. The program will ask the user for two integer numbers and will divide the dividend by the divisor.It will then output the results(quotient) and...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.