Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 8 of 8

Thread: Question about rounding

  1. #1
    Junior Member
    Join Date
    Sep 2011
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Question about rounding

    Is there a way in Java to round a number without using and external class such as Math and the method from the class to round up the number?

    And if possible how to round to the nearest integer,while rounding according to the halfway up criteria.

    I seen mention in a topic entitled "Mathematics in Java" where a user mentioned using a substring. Also I heard by type casting the number ,if the variable is a float or double, into a long variable. A

    Any ideas?

    Thank you very much.
    Last edited by CoolGuy134; September 26th, 2011 at 08:43 PM.


  2. #2
    Super Moderator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,097
    Thanks
    169
    Thanked 779 Times in 725 Posts
    Blog Entries
    5

    Default Re: Question about rounding

    Is there a way in Java to round a number without using and external class such as Math and the method from the class to round up the number?
    Why not use an external class? To use primitives, multiply the floating point variable by a multiplier of 10, cast to an int, cast back to the original type and divide by the same multiplier. Use the following syntax to cast a variable:
    float fVal = 1.111f;
    int iVal = (int)fVal;

  3. #3
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Question about rounding

    Un-optimized, and probably overkill. However, it will maintain all exponents correctly, and works with the two infinities and NaN.

    	public static double round(double original_value)
    	{
    		long value = Double.doubleToLongBits(original_value);
    		// extract the exponent
    		long exponent = (value & 0x7FF0000000000000L) >> 52;
    		long mantissa = value & 0x000FFFFFFFFFFFFFL | 0x0010000000000000L;
    		exponent -= 0x3FFL;
    		if (exponent <= -2)
    		{
    			return 0;
    		}
    		else if (exponent == -1)
    		{
    			return 1;
    		}
    		else if (exponent < 52)
    		{
    			long mask = 0xFFFFFFFFFFFFFFFFL >>> 52 - exponent << 52 - exponent;
    			value &= mask;
    			if ((mantissa & 1L << 51 - exponent) != 0)
    			{
    				// round up
    				return Double.longBitsToDouble(value) + 1.;
    			}
    			// round down
    			return Double.longBitsToDouble(value);
    		}
    		else
    		{
    			return original_value; // no rounding needed
    		}
    	}

    A similar solution exists for floats.
    Last edited by helloworld922; September 27th, 2011 at 12:23 AM.

  4. #4
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Question about rounding

    (copeg) multiply the floating point variable by a multiplier of 10
    I'm not sure - I didn't actually try it - how that would round 1.5 to 2. Does it work?

    The way I would usually do this is through observing that 'nearest' is a two-way split: it's either next one up or previous one down. If you multiply a floating point number by two, then the integer part is 2x the original integer part for all fractional parts less than 0.5. If the fractional part is 0.5 or greater, the integer part of the doubled number is 2x + 1 the original integer part. If you add 1 to the doubled result and convert it to an integer, this new integer is either 2x + 2 or 2x + 1 depending on whether the original fractional part was greater than 0.5 or less than 0.5. Halving this integer gives you either x + 1 or x, depending on whether ... you know.

    Double.doubleToLongBits(
    I was getting ready to pontificate about 'relying on implementation details', but on reading the API doc I see this method is badly named. Using Double.doubleToIEEE754DoubleBits(double) is of course an entirely reasonable and reliable way of doing it as long as IEEE754 is immutable.

  5. #5
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Question about rounding

    Well, technically the Java Language Specifications spells out specifically how a double and float are represented. If the IEEE754 standard changes, then the Java Language Specification will just not comply to that standard

    Of course, if that happens, a lot of hardware is going to break first since most hardware FPU's implement the current IEEE754 standard (or a previous version, which uses the same bit formatting).

  6. #6
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Question about rounding

    spells out specifically
    It does spell out specifically, but not how double and float are implemented:
    float and double, which are conceptually associated with the single-precision 32-bit and double-precision 64-bit format IEEE 754 values
    This is what I expect the Java specification to be: no commitment to implementation details at the binary level. It doesn't matter what the IEEE754 standard is at the binary level - the entire point of the JVM and the JLS is to provide a compatibility layer for the underlying platform on which Java applications run.

    A *conceptual* association means you can use it in any way that you would use a 'raw' IEEE754 value, but no promise is made as regards its binary implementation. Note that with doubleToLongBits you are not inspecting the binary implementation of a double, but from the API doc for doubleToLongBits():
    a representation of the specified floating-point value
    - it doesn't matter how double is implemented by the JVM and (as far as I know) no method exists to check its implementation. While doubleToLongBits returns an IEEE754-1985 binary representation from a Java-native double, your method will continue to work, by design.

    Your approach is valid - you're obtaining a representation of a value that is no more and no less valid than the original, but which comes with some extra information you can test. It would be bad if you were testing the underlying implementation - but by specification ("conceptually associated") and implication (there's a method to create an IEE754 representation) you're not. Even if a Java double is implemented at the binary level as IEEE754 suggests, it doesn't affect the validity of your method (or my argument as to why your method *is* valid when at first glance it looks like a kludge) because you're not operating on the underlying implementation (which is usually a SlightlyBadThing), but a well-specified representation of that double value.

    Are you familiar with JNI? I keep meaning to try out some long-lived compute-intensive code I have with a C++ implementation, but I'm scared of compromising the reliability of a pure-Java implementation. I see from a quick look at the WWW that when you write C++ code to manipulate Java doubles, the C++ code seems to always use a 'jdouble' type that must be from a C++-native library. I would have expected if there was any direct implementation similarity between Java doubles and C++ doubles that there'd be a trivial correspondence between Java double and C++ double. This page at SO makes me think that a lot of programming languages may be using 'conceptual association'!
    Is there an open-source c/c++ implementation of IEEE-754 operations? - Stack Overflow

    Does it look like I'm arguing with you? I'm still trying to explain why I *nearly* criticised your method, but didn't and still haven't. It's an entirely valid approach to a problem in double, but the reason why is a bit convoluted.

  7. #7
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Question about rounding

    Ah, true that there's no guarantee of the ordering of the bits, only that they must be able to hold those values

    most languages I know of don't actually manipulate floating point numbers (or even integer numbers) at that level normally. Instead, it's handled by hardware. That's the whole purpose of FPU's, which is where I think the "conceptual association" comes from. Personally I'm much more likely to trust hardware than software since many modern hardware companies "prove" their hardware, not just present test cases.

    I have worked with JNI a little bit, it's fairly simple to use except for a few minor details which may catch you off guard. As far as I know, doubles in Java and in C++ are represented the same (due to a similar reliance on the underlying hardware implementation).

  8. #8
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Question about rounding

    Instead, it's handled by hardware
    Hardware is a big space. Every compiled programming language will provide a maths library or attempt to use maths routines offered by the OS. The amount of work done in software and delegated to hardware will vary enormously from platform to platform. Check out some of these well known platforms:

    ARM A9 - FPU is optional?:
    Cortex-A9 Processor - ARM
    Optional NEON™ media and/or floating point processing engine
    Some embedded x86 have no FPU:
    Using software floating point on x86 linux - Stack Overflow
    Partial support on MIPS:
    Floating point - LinuxMIPS

    The conceptual association in the JLS is certainly from the point of view of use of Java double: it's telling you you can do anything with a Java double you might expect to do with an IEEE754-1985 (not a -2008 one!) double. The nitty-gritty of floating point computation may be delegated by the JVM to whatever support exists on the target platform - but I suspect it could be difficult to guarantee that the results of double computations are identical across all JVMs unless they're carried out in software by the JVM itself.

    much more likely to trust hardware
    Are you assuming 'black box so it must work'? This is a great James Gosling article which touches on a lot of the issue brought up by this discussion. You'll never use floating point again:
    James Gosling: on the Java Road - Transcendental Meditation

Similar Threads

  1. Rounding the numbers
    By lakshmivaraprasad in forum What's Wrong With My Code?
    Replies: 1
    Last Post: September 2nd, 2011, 12:45 AM
  2. Rounding long or floating numbers, or longs for that matter.
    By SPACE MONKEY in forum What's Wrong With My Code?
    Replies: 3
    Last Post: February 27th, 2011, 11:32 PM
  3. Rounding an int. Help please
    By Akim827 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: November 18th, 2010, 11:36 PM
  4. [SOLVED] Why is my float automatically rounding and how do i get it to stop
    By Perd1t1on in forum What's Wrong With My Code?
    Replies: 18
    Last Post: August 26th, 2010, 01:41 PM
  5. Rounding screwed up?
    By The_Mexican in forum What's Wrong With My Code?
    Replies: 5
    Last Post: February 6th, 2010, 12:43 PM

Tags for this Thread