java


Difference in BigDecimal behavior


I have two pieces of code new BigDecimal("1.240472701") and new BigDecimal(1.240472701). Now if i use compareTo method of java on both the methods then i get that they are not equal.
When i printed the values using System.out.println() method of java. I get different results for both the values. For example
new BigDecimal("1.240472701") -> 1.240472701
new BigDecimal(1.240472701) -> 1.2404727010000000664291519569815136492252349853515625
So i want to understand what could be reason for this?
Since user thegauravmahawar provided the answer from docs. Yes, it is because of Scaling in BigDecimal case.
So the values might seem equal to You but internally java uses Scaling while storing the value of BigDecimal type.
Reason: Scaling.
Improvement:
You could call setScale to the same thing on the numbers you're comparing:
like this
new BigDecimal ("7.773").setScale(2).equals(new BigDecimal("7.774").setScale (2))
This will save you from making any mistake.
You can refer the Java doc of public BigDecimal(double val) for this:
public BigDecimal(double val)
Translates a double into a BigDecimal
which is the exact decimal representation of the double's binary
floating-point value. The scale of the returned BigDecimal is the
smallest value such that (10^scale × val) is an integer.
The results of this constructor can be somewhat unpredictable. One
might assume that writing new BigDecimal(0.1) in Java creates a
BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with
a scale of 1), but it is actually equal to
0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that
matter, as a binary fraction of any finite length). Thus, the value
that is being passed in to the constructor is not exactly equal to
0.1, appearances notwithstanding.
The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates
a BigDecimal which is exactly equal to 0.1, as one would expect.
Therefore, it is generally recommended that the String constructor be
used in preference to this one.
When a double must be used as a source
for a BigDecimal, note that this constructor provides an exact
conversion; it does not give the same result as converting the double
to a String using the Double.toString(double) method and then using
the BigDecimal(String) constructor. To get that result, use the static
valueOf(double) method.
The string "1.240472701" is a textual representation of a decimal value. The BigDecimal code parses this and creates a BigDecimal with the exact value represented in the string.
But the double 1.240472701 is merely a (close) approximation of that exact decimal value. Double cannot represent all decimal values exactly, so the exact value stored in the double differs slightly. If you pass that to a BigDecimal, it takes that differing value and turns it into an exact BigDecimal. But the BigDecimal only has the inexact double to go by, it does not know the exact text representation. So it can only represent the value in the double, not the value of the source text.
In the first case:
String --> BigDecimal
Because BigDecimal is made to exactly represent decimal values, that conversion is exact.
In the second case:
1 2
Source code text --> double --> BigDecimal
In the second case, precision is lost in the first conversion (1). The second conversion (2) is exact, but the input -- the double -- is an inexact representation of the source code text 1.240472701 (in reality, it is 1.2404727010000000664291519569815136492252349853515625).
So: never initialize a BigDecimal with a double, if you can avoid it. Use a string instead.
That is why the first BigDecimal is exact and the second is not.

Related Links

Applet based application stopped working after upgrading to Java
Java, JMS shutdown connection when receive all response.
How to create the hibernate custom query which returns hashmap values in dao
Validate data before saving in Mongo db (Reactive)
OneToMany bidirectional mapping is not saving its foreign key
How to used Libgdx Scene2d Dialog?
Java: Display unicode chars as chars when printing string [duplicate]
Fragment onAttach() with tablayout not being called
How to declare a method returning generic class?
How to pass string in json object?
Tomcat startup takes huge time with my Spring application
Javax mail sendpulse smtp server
Getting weblogic.management.NoAccessRuntimeException on creating webservice of java class
Spring Data + JPA > New entries of “mappedBy” property are not fetched from DB after SQL INSERT
How do I make a .jar file with a .jar file? [closed]
What is the use of inheritance if the same thing can be done by creating package? [closed]

Categories

HOME
sendgrid
twitter
google-chrome-extension
pypi
keras
dictionary
session
framework7
spring-jdbc
jgroups
ezpublish
indesign
swagger-ui
add
primary-key
here-api
u-sql
google-apps-marketplace
zend-framework3
size
visual-studio-2005
systemc
foselasticabundle
facebook-page
serilog
text-rendering
viewport
visual-composer
predix
orleans
sylius
crosstab
apache-commons-io
brunch
publish
buck
log4js-node
bpel
twilio-api
oracle-fusion-middleware
code-contracts
mapdb
html5-fullscreen
reportbuilder
sqlite2
jna
unoconv
eclipse-scout
quadratic-programming
elmah
texmaker
convertapi
apache-fop
diagnostics
font-size
nsarray
smart-table
migradoc
google-cdn
infix-notation
log4c
gridview-sorting
suffix-tree
tform
wapiti
photobucket
freelancer.com-api
historian
kendonumerictextbox
pervasive-sql
thredds
cannon.js
spidermonkey
mmc
angular-local-storage
bridge.net
python-green
tween
bitcoinj
heisenbug
dml
message-driven-bean
algebraic-data-types
intentservice
inbox
apc
dbconnection
rabl
path-separator
armcc
labwindows
tridion-worldserver
tomcat-valve
yetanotherforum
fluent-interface
subviews
zend-translate
paster
revisions
filtered-index
meego
putchar
mdac
lzh

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App