Division of int by double


 
Thread Tools Search this Thread
Top Forums Programming Division of int by double
# 1  
Old 08-01-2014
Division of int by double

A simple arithmetic example: 1680 / 1.12 = 1500

My C code result is 1499, here is the code:
Code:
 
  
 #include <stdio.h>
main(int argc, char *argv[])
{
  int           t       = 1680;
  double        adj     = 1.12;
  int           ires    = t / adj;
  double        fres    = t / adj;

         printf("int result = %i, float res=%.6f\n", ires, fres);
        return(0);
}

I compiled and run this code as

Code:
 
 cc -o c c.c && ./c
 int result = 1499, float res=1500.000000

I tried it on old SCO 5.07, Ubuntu 8.04 (32 bit) and Ubuntu 12 (64 bit) on different h/w, the result is the same 1499 instead of 1500.

Is there any way to produce correct 1500 result?
Thanks in advance.
# 2  
Old 08-01-2014
If you print it to the maximum precision a double really gives you, you will see that it's not really 1500 -- it's 1499.999999999999773. The .999999999999773 is truncated down to 0 since floating point numbers "round down" when you convert to int.

Just add 0.5 to the number before converting to integer to make it round the way you expect.

Code:
int           ires    = (t / adj)+0.5f;

This User Gave Thanks to Corona688 For This Post:
# 3  
Old 08-01-2014
To expand a little on what Corona68 said... Although 1.12 is a nice terminating decimal value, the corresponding binary number is a non-terminating sequence (just like 1/3 in decimal arithmetic is a non-terminating .33333...).

For IEEE Std 754 double precision floating point, you get 15-17 significant digits for individual values. As you perform multiplications and divisions, the founding errors add up. If you add or subtract small numbers to or from large numbers, the small numbers may disappear completely.

When you assign a double precision floating point value to an integer object, the result is truncated, not rounded; but you can do the rounding on your own. To see what happened, try this:
Code:
#include <stdio.h>
int main(int argc, char *argv[])
{
	int	t	= 1680;
	double	adj	= 1.12;
	int	ires	= t / adj;
	double	fres	= t / adj;
	int	rires	= t / adj + .5;

	printf("adj =\t%.20f\n", adj);
	printf("fres =\t%.20f\n", fres);
	printf("ires =\t%i\n", ires);
	printf("rires =\t%i\n", rires);
        return(0);
}

which produces:
Code:
adj =	1.12000000000000010658
fres =	1499.99999999999977262632
ires =	1499
rires =	1500

These 2 Users Gave Thanks to Don Cragun For This Post:
# 4  
Old 08-01-2014
Thank you for your in-depth explanation.

I tried the same in Java, and to my surprise it behaves differently:

Code:
class n1
{
 public static void main(String[] args)
 {
  int i = 1680;
  float d = 1.12f;
  int ires = (int)(i / d);
  float dres = i / d;
 System.out.format("ires = %d, dres = %.15f\n", ires, dres);
 }
}

I run it like this
Code:
 
 javac n1.java
 java n1
 ires = 1500, dres = 1500.000000000000000

Just a note - I could not say int ires = i / d; as Java complains about loss of precision, so I needed to be explicit here.

I don't know a lot about Java, I hope somebody would explain the different behavior here.
# 5  
Old 08-02-2014
Quote:
Originally Posted by migurus
Thank you for your in-depth explanation.

I tried the same in Java, and to my surprise it behaves differently:

Code:
class n1
{
 public static void main(String[] args)
 {
  int i = 1680;
  float d = 1.12f;
  int ires = (int)(i / d);
  float dres = i / d;
 System.out.format("ires = %d, dres = %.15f\n", ires, dres);
 }
}

I run it like this
Code:
 
 javac n1.java
 java n1
 ires = 1500, dres = 1500.000000000000000

Just a note - I could not say int ires = i / d; as Java complains about loss of precision, so I needed to be explicit here.

I don't know a lot about Java, I hope somebody would explain the different behavior here.
If you take the C program I gave you before and change all of the "double"s to "float"s, you'll get the output:
Code:
adj =	1.12000000476837158203
fres =	1500.00000000000000000000
ires =	1500
rires =	1500

instead of the earlier results shown when using type double.

Using double made the difference between the binary floating point representation of 1.12 and the exact decimal value affect the results. With different values, both float and double could give you results just above, just below, or an exact match to the the decimal evaluation (and when the float and double values are inexact, one could be above and the other could be below the exact value). Typecasting floating point value using (int) in both C and Java truncates. In C you can round using:
i = f + .5;
In Java you can round using:
Code:
i = Math.round(f);
      or
i - (int)(f +.5);

It has been a while since I've written any Java code (and I haven't tested the following), but did you try something like:
Code:
class n1
{
 public static void main(String[] args)
 {
  int i = 1680;
  double d = 1.12d;
  int ires = (int)(i / d);
  double dres = i / d;
  System.out.printf("ires = %d, d = %.20f, dres = %.20f\n", ires, d, dres);
 }
}

Note that using .printf() and using .format() in Java and using printf() in C round values; they don't truncate like a conversion from a floating point type to an integral type.

Last edited by Don Cragun; 08-02-2014 at 01:21 AM.. Reason: Fix typos.
# 6  
Old 08-02-2014
Thank you for the explanation.

I did try your suggestion to experiment with float, but my results still show ires = 1499

See below:
Code:
 #include <stdio.h>
main(int argc, char *argv[])
{
  int   t       = 1680;
  float adj     = 1.12;
  int   ires    = (int)(t / adj);
  float fres    = t / adj;
  int   rires   = t / adj + 0.5;
 
        printf("adj =\t%.20f\n", adj);
        printf("fres =\t%.20f\n", fres);
        printf("ires =\t%i\n", ires);
        printf("rires =\t%i\n", rires);
         return(0);
}

 cc -o c c.c && ./c
adj =   1.12000000476837158000
fres =  1500.00000000000000000000
ires =  1499
rires = 1500

Tried this on three systems I mentioned above.

Just out of curiosity - why C does not have decimal(n,m) fixed-point data type? I think if I had a fixed-point available here I won't see the problem I am having.
# 7  
Old 08-02-2014
With the code:
Code:
#include <stdio.h>
int main(int argc, char *argv[])
{
	int	t	= 1680;
	float	adj	= 1.12;
	int	ires	= (int)(t / adj);
	float	fres	= t / adj;
	int	rires	= (int)(t / adj + .5);

	printf("adj =\t%.20f\n", adj);
	printf("fres =\t%.20f\n", fres);
	printf("ires =\t%i\n", ires);
	printf("rires =\t%i\n", rires);
        return(0);
}

with or without the text shown in red, on Mac OS X 10.9.4, I get the output:
Code:
adj =	1.12000000476837158203
fres =	1500.00000000000000000000
ires =	1500
rires =	1500

which seems to match what you showed us from your Java code.

It is interesting that you're getting the line:
Code:
adj =   1.12000000476837158000

while I'm getting:
Code:
adj =	1.12000000476837158203

But, as I said before, as long as you're performing floating point arithmetic (float, double, or long double) where one of the operands or the result of a division does not have an exact representation may produce a result that is slightly higher or slightly lower than the exact decimal calculation would yield. Any time you are converting a floating point value to integer you need to take care to make adjustments suitable for the results you want given the limitations of floating point arithmetic. (Note that depending on what values you're expecting and the operations that have been performed, adding .5 before converting to int might or might not be appropriate.)

I would assume that C doesn't include a decimal data type because the hardware on which C was initially developed didn't include instructions to process binary coded decimal data (and a lot of hardware today doesn't either).

Have you looked for an open-source version of the dc utility source to see how it handles arbitrary precision arithmetic?

I don't have any experience with it, but have you looked at XBCD_Math?
This User Gave Thanks to Don Cragun For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Division of wc output

I have a function that outputs 3 lines for each result and I want to know how many results there are. so for example function | wc -l 24 but I want to see the result 8. so is there a easy way to divide the result? (5 Replies)
Discussion started by: yatici
5 Replies

2. UNIX for Dummies Questions & Answers

Help in division

hi, The below commands result only the whole number(not giving the decimal values). pandeeswaran@ubuntu:~$ echo 1,2,3,4|sed 's/,/\//g'|bc 0 pandeeswaran@ubuntu:~$ echo 1000,2,3|sed 's/,/\//g'|bc 166 How to make it to return the decimal values? Thanks (5 Replies)
Discussion started by: pandeesh
5 Replies

3. UNIX for Advanced & Expert Users

awk: division by zero

I received error "awk: division by zero" while executing the following statement. SunOS 5.10 Generic_142900-15 sun4us sparc FJSV,GPUZC-M echo 8 | awk 'END {printf ("%d\n",NR/$1 + 0.5);}' file1.lst awk: division by zero Can someone provide solution? Thanks Please use code... (11 Replies)
Discussion started by: kumar77
11 Replies

4. Programming

Handle int listen(int sockfd, int backlog) in TCP

Hi, from the manual listen(2): listen for connections on socket - Linux man page It has a parameter called backlog and it limits the maximum length of queue of pending list. If I set backlog to 128, is it means no more than 128 packets can be handled by server? If I have three... (3 Replies)
Discussion started by: sehang
3 Replies

5. Shell Programming and Scripting

division by zero

Hello, I am searching for a way to calculate for example 10/100 within a shellscript and the result should be 0.1 and not just 0. Every alternative i tried just results 0 Thank you in advance 2retti (6 Replies)
Discussion started by: 2retti
6 Replies

6. Shell Programming and Scripting

how to check for division by zero

i have a script that is doing the following: awk 'BEGIN {FS=","} ; {printf("%.10f",($5 - $2)/(3 * $3))}' data > test now some records in $3 contain zeroes. i don't want to remove those records. is it possible to check for division by zero and then write a "N/A" for that record in the o/p... (2 Replies)
Discussion started by: npatwardhan
2 Replies

7. Shell Programming and Scripting

division by 0 error

Hi, I am writing a script that among other things will be checking for various files on mount points. One of the conditions is that unless the server has failed over the df command will show root ( / ). If when checking the files the script comes across /, I want it to skip it, otherwise to... (2 Replies)
Discussion started by: cat55
2 Replies

8. UNIX for Dummies Questions & Answers

Problem in division

hi I am having two variables namely a=7 & b=8. I have to subtract these two variables. I am using the command c=`expr $a / $b` When I check the value of c, it comes out to be zero. Please help. Regards Rochit (9 Replies)
Discussion started by: rochitsharma
9 Replies

9. UNIX for Dummies Questions & Answers

int open(const char *pathname, int flags, mode_t mode) doubt...

hello everybody! I want to create a file with permissions for read, write, and execute to everybody using C, so I write this code: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(){ int fileDescriptor; fileDescriptor =... (2 Replies)
Discussion started by: csnmgeek
2 Replies

10. Programming

difference between int ** func() and int *& func()

What is the difference between int** func() and int*& func(). Can you please explain it with suitable example. Thanks, Devesh. (1 Reply)
Discussion started by: devesh
1 Replies
Login or Register to Ask a Question