get double value from bigdecimal without exponential java - double

is there a way to get double from BigDecimal without exponential?
Eg: I have an new BigDecimal("123456797676.897")
if i print new BigDecimal("123456797676.897").toString() it prints properly as 123456797676.897.
Now suppose if I try to print new BigDecimal("123456797676.897").doubleValue(), it prints with exponential like 1.23456797676897E11.
Is there any way I can get doublevalue with out exponential.
Thanks :)

The following program demonstrates that these are all exactly the same double:
new BigDecimal("123456797676.897").doubleValue()
123456797676.897
1.23456797676897E11
12.3456797676897E10
The Double toString method has to pick one representation for each value. For numbers greater than 107 it uses exponential notation with a single digit before the decimal point. That is a generally reasonable choice, but it is not always the right choice. If you want it displayed without the exponent use DecimalFormat. If you are just using the number, it makes no difference whether Double's toString would have displayed it with an exponent or not, and you don't need to do anything about it.
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
double doubleValue = new BigDecimal("123456797676.897").doubleValue();
double simpleLiteral = 123456797676.897;
double exponent11Literal = 1.23456797676897E11;
double exponent10Literal = 12.3456797676897E10;
System.out.println(doubleValue == simpleLiteral);
System.out.println(doubleValue == exponent11Literal);
System.out.println(doubleValue == exponent10Literal);
}
}
output:
true
true
true

Related

Even though decimal digit are correct, assert are getting failed

I have those 2 values :
Expected Value (fResult)= 103393.431493782901937514
Actual Value (output) = 103393.431493782901937514
When I assert on the value, my expected result was consider as 103393.431493783m
Because of that my Assert was fails. Can anyone help in this regard.
Assert.That(output, Is.EqualTo(fResult));
More Information: both Actual and Expected values are Decimal data type,
[TestCase("value1", "value2", 5, 103393.431493782901937514)]
public void converFormulaforPressure(String Fromunit, String toUnit, decimal Avalue, decimal fResult) {
var output = ut1.Convert(ut1.GetUnit("Pressure", Fromunit), ut1.GetUnit("Pressure", toUnit), Avalue).Val;
Assert.That(output, Is.EqualTo(fResult));
}
ut1.Convert is a method which converts the value and give the Actual result .
You need to provide a tolerance level and you cannot pass a decimal as a TestCase parameter. The code you provided is passing the last value as a double, hence the rounding when you run the assert. You can solve this by using TestCaseSource instead.
The test below passes:
private static readonly object[] TestCases = {
new object[] {"value1", "value2", 5m, 103393.431493782901937514m}
};
[Test, TestCaseSource("TestCases")]
public void TestExample(string fromUnit, string toUnit, decimal value, decimal fResult) {
//Replace the line below with your convert method using values from testCase
var output = 103393.431493782901937514m;
Assert.That(output, Is.EqualTo(fResult).Within(0.00000000000001));
}

NTriplesParser extract textual value from string

I am using dotnetrdf and trying to parse some triples with NTriplesParser. I have my own handler RobHandler in which I process each triple in turn.
public class RobHandler : BaseRdfHandler
{
protected override bool HandleTripleInternal(Triple t)
{
string predicateUrl = ((BaseUriNode)(t.Predicate)).Uri.AbsoluteUri;
string value = t.Object.ToString();
}
}
This works fine but I want to get the object minus the language. My objects look like "Lincoln"#en. I could obviously write some code to remove the #en bit, but I'd rather use some library code rather than my own that hard-coded strings like #en. To do this I think I need to create a LiteralNode but there doesn't seem to be a way to get from a string which is what I have (my variable value) to a LiteralNode.
How can I extract just the textual value from an object string?
Actually I think I have the answer myself:
if (t.Object.NodeType == NodeType.Literal)
{
var node = (ILiteralNode)t.Object;
}

How to make JavaFX Chart NumberAxis only show Integer value,not double

I'm trying to create a chart who's yAxis is designed to show number of employee number, so it must only show whole numbers.
But I found it's not that easy as I already tried to yAxis.setTickUnit(1) but it won't work when the values are small(etc. the max value is 3, it'll still show 0.5,1.5..., I only want tick value like 1,2,3,4..)
How Could I to achieve this?
According to #jewelsea 's answer, I tried this(In javafx 2.2 jdk7)
class IntegerStringConverter extends StringConverter<Number>{
public IntegerStringConverter() {
}
#Override
public String toString(Number object) {
if(object.intValue()!=object.doubleValue())
return "";
return ""+(object.intValue());
}
#Override
public Number fromString(String string) {
Number val = Double.parseDouble(string);
return val.intValue();
}
}
It's result is kind of acceptable. Double value's are gone, but there ticks are still there.
Set a tickLabelFormatter on the axis.
You can set the NumberAxis(double lowerBound, double upperBound, double tickUnit) values by using the constructor. This works fine for JaxaFX 8, in case people like me are still looking for this.
Source:
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/chart/NumberAxis.html

Float inaccurate rounding in Mongodb with CS driver

When I save the float number into MongoDB using csharp driver it is not saved accurately. If my number is 1504.57 I expect the database will have the same number but for some reason it become 1504.56994628906 (with Double type in MongoDB). What's going on? How to keep data accurately?
My object keep all the field as object types and cast them on the fly depending on the type, for example:
this.Values[i] = float.Parse(this.Values[i].ToString());
Maybe is it the reason of this strange behavior? But after casting this.Values[i] is pretty accurate and it's spoiled only in database.
Thanks
Update.
The class that incapsulates data:
public class TransferredData
{
[BsonElement("_id")]
[ScriptIgnore]
public ObjectId Id { get; set; }
public class Data
{
public List<Object> Values { get; set; }
public DateTypes DataType { get; set; }
public void CastToType()
{
for (int i = 0; i < this.Values.Count; i++ )
{
if (this.DataType == DateTypes.Date)
{
DateTime dt = DateTime.Parse(this.Values[i].ToString());
this.Values[i] = dt.ToUniversalTime().Date;
}
else if (this.DataType == DateTypes.Other)
{
this.Values[i] = this.Values[i].ToString();
}
else if (this.DataType == DateTypes.Reading)
{
this.Values[i] = float.Parse(this.Values[i].ToString());
}
}
}
}
}
I use Object type because I don't know which actual type it could be. So, just before doing upsert I fill up this class by data and then call Cast method.
Then I save it into db:
data = new TransferredData();
...
data.Values[1] = "1504.57"; // Because the input is always string
data.CastToType(); // Here data.Values[1] = 1504.57 - cool
TransferredDataCollection.Save<TransferredData>(data, SafeMode.True);
After this moment, looking into database... it's 1504.56994628906
IEEE 754 floating point formats cannot represent every single number accurately. As such your issue cannot be avoided and works as intended.
You should not ever use floating point formats if you need absolute guarantees that input=output while you cannot guarantee that the input can be accurately represented by the used floating point format.
Most people run into these problems when they try to store monetary values in floats which is universaly accepted to be an extremely bad idea. If you need to store monetary values save it as an integer value, usually as cents.
i imagine this has something to do with the representatioh of 1504.57 as a double precision floating point #.
perhaps there are a couple options, one being to round off the excess digits and the other being to store cents instead of dollars if the number is a currency #.
I would echo all the above comments that floating point numbers often exhibit interesting rounding errors when converted from decimal to binary and back.
In your particular case, the rounding errors are being introduced by the C# language itself, not by the C# driver. MongoDB does not natively support single precision floating point numbers, so your C# float values are being converted by the C# driver to doubles before being sent to the database. It is during this conversion that the rounding errors occur.
Here's a small snippet of C# code that demonstrates how casting a float to a double introduces the rounding errors:
var f = (float)1504.57;
var d = (double)f;
Console.WriteLine(f);
Console.WriteLine(d);
As others have recommended, if you must have 100% precision you should use some other data type than float or double.

MongoDB C# offi : Lat, Lng as doubles are stored at precision13 and rounding?

I store lat and lng as double in MondoDB and C# official driver. I have problems with my points that are not matching the right places after a rounding of double values internaly in MondoDB(by driver or intern). I have searched all posible rounding before post to the Repository but haven´t found anything. Why not use decimal, because Query.Near use doubles.
v1.6.5 ; C#v0.11 ; Win64.
XX.444057295828145;XX.63416004180907 Captured as string
XX.444057295828145;XX.63416004180907 Receipt by Repository before Save method
Inside MongoDB and returned :
XX.4440572958281, XX.6341600418091, Saved and returned (only 13 after dot)
This is resulting to a moved map. Advices. Thanks.
I use this Update method
public void SaveGeoPoints(String id, String lat, String lng)
{
//--> XX.444057295828145;XX.63416004180907
Db.repository.Update(
Query.EQ("_id", id),
Update.Set("Lat", double.Parse(lat))
.Set("Lng", double.Parse(lng)));
}
the default format for Console.WriteLine prints only 13 digits after the decimal point. The following code snippet shows this
var test = "10.444057295828145";
Console.WriteLine(test);
var testInDouble = double.Parse(test);
Console.WriteLine(testInDouble);
Console.WriteLine(testInDouble.ToString("R"));
Console output is
10.444057295828145
10.4440572958281
10.444057295828145
I am unable to reproduce what you are describing. I can save and retrieve those values from MongoDB without loss of precision. Here's the test code I used:
http://www.pastie.org/1599603
As an additional test I verified the contents of the documents in the database using the Mongo shell.
There must be some rounding going on somewhere else. I would check all places where you convert back and forth between doubles and strings.
Here's another test that uses the Update.Set method:
http://www.pastie.org/1599777
I still see no loss of precision when storing values to the database and reading them back.
You don't say what your typical values of XX are. I'm using 12 in the test.
Note that double only has a total precision of slightly over 15 decimal digits (doesn't matter where the decimal point is), so the larger your values of XX the less precision that is left over to use to the right of the decimal point.
If you are simply exceeding the precision limits of the 64 bit IEEE double type that is not anything to do with either the C# driver or MongoDB.
Thanks Sam and bugai for this help. Of course all answers are corrects. It's a limits of C# double and printings in C# like point Bugai in upper post. I post here the logical used to others users like me that lost the North with this amount of decimals. Not use double? is not accepting round-trip format. Use round-trip formatter in your outputs to Api. Thanks for comprension. Get Location now having 15 decimals. P.R
public class BsonCentroid
{
[BsonId]
public String Id { get; set; }
public String Location
{
get { return String.Format("{0};{1}", Lat.ToString("r"), Lng.ToString("r")); }
}
public double Lat { get; set; }
public double Lng { get; set; }
}