I'm trying to add to documentDB document with property:
"Value": 849.30000000000007
After using CreateDocumentAsync method for add document to documentDB, in my collection have number without last digit:
"Value": 849.3000000000001
How can I add this property right? Thanks for help.
As Jon pointed out, JavaScript has one number type Number, a 64-bit IEEE 754 float which is often referred to as a "double". You could use strings to represent it as a true decimal. Then you'll have to resort to a 3rd party decimal library (like big.js for node.js, or the equivalent for your platform) to do any maths on the values.
Alternatively, you may be able to use integers and assume a particular exponent (think scientific notation) or store the exponent in another field. Again, this poses problems for doing maths on it.
Related
So small question, I've been looking into moving part of my C# code to C++ for performance reasons.
Now when I look at my float.Epsilon in C# its value is different from my C++ value.
In C# the value, as described by microsoft is 1.401298E-45.
In C++ the value, as described by cppreferences is 1.19209e-07;
How can it be that the smallest possible value for a float/single can be different between these languages?
If I'm correct, the binary values should be equal in terms of number of bytes an maybe even their binary values. Or am I looking at this the wrong way?
Hope someone can help me, thanks!
The second value you quoted is the machine epsilon for IEEE binary32 values.
The first value you quoted is NOT the machine epsilon. From the documentation you linked:
The value of the Epsilon property is not equivalent to machine epsilon, which represents the upper bound of the relative error due to rounding in floating-point arithmetic.
From the wiki Variant Definitions section for machine epsilon:
The IEEE standard does not define the terms machine epsilon and unit roundoff, so differing definitions of these terms are in use, which can cause some confusion.
...
The following different definition is much more widespread outside academia: Machine epsilon is defined as the difference between 1 and the next larger floating point number.
The C# documentation is using that variant definition.
So the answer is that you are comparing two different types of Epsilon.
C++
Returns the machine epsilon, that is, the difference between 1.0 and the next value representable by the floating-point type T.
https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
C#
Represents the smallest positive Single value that is greater than zero. This field is constant.
https://learn.microsoft.com/en-us/dotnet/api/system.single.epsilon?view=net-5.0
Conclusion
C# has next value from 0, C++ has next from 1. Two completely different things.
Edit: The other answer is probably more correct
From the link you referenced, you should use the value FLT_TRUE_MIN ("minimum positive value of float") if you want something similar to .NET Single.Epsilon ("smallest positive single value that is greater than zero").
I have a problem that I need advice: I have to make calculations with big numbers, in the range of (plus/minus, signed); integer part: 70*(10^27) and accuracy, decimal part: 9*(10^-31). Most of the times I only simple simple operations (add/subtr/mult/div) where I could ignore most digits (use only 8 decimals) of the decimal part - however, in many cases, I would have to take the 'whole' decimal and do calculations with that precision (and store the result which is used in subsequent calculations).
An example of a number:
66898832014839425790021345548 . 8499970865478385639546957014538
I saw the articles on decimal vs long etc. Should I use a decimal or should a custom type be made? If yes on the later, how may I do simple arithmetic operations? (Roundation of the last decimal only is acceptable)
My projects are all in C# and SQL Server; thank you very much in advance.
There is no standard implementation in C#, but you can create your own library based on BigInteger like
public BigDecimal(BigInteger integer, BigInteger scale)
You can also reference some 3rd-party libraries like GMP with its .Net forks/ports like Math.Gmp.Native.NET, libgmp, etc.
There are some custom libs, as Franz Gleichmann already mentioned in his comment: BigDecimal, AngouriMath
For SQL Server most of the libraries use strings to store such kind of data. For instance, in Java there is BigDecimal and it is mapped to string via JDBC.
I am using Googles protocol buffer library within my persistent storage system and want to persist currency values, but I am not sure that the floating point types provided by photo (float/double) are good enough. Are there any downsides to storing all of my currency values as strings (e.g. storing "0.10" instead of 0.1), then using the Convert.ToDecimal function when I retrieve my data and need to do arithmetic?
You are correct in anticipating that float/double data types are not suitable for "currency!"
Consider how SQL databases (and, uhh, COBOL programs ...) commonly store "currency" values: they use a decimal representation of some sort. For instance, a true COBOL program might use a "binary-coded decimal (BCD)" data type. A Microsoft Access database uses a "scaled integer": the dollars-and-cents value multiplied by 10,000, giving a fixed(!) "4 digits to the right of the decimal."
For the immediate purposes of this question, I would definitely store the values as strings, and then give very serious thought to the number of digits to be stored and just how to handle "rounding" to that number of digits. (For instance, there are algorithms such as “banker’s rounding.”)
“Storage size?” You don’t care about that. What you do care about is, that if a particular customer (or, auditor ...) actually adds-up all the numbers on a printed statement, the bottom-line on that piece of paper will agree ... at the very(!) least, within a single penny.
I made a query to SQL Server to get some data via a Stored Procedure, the returned value was this:
10219150
Then, in an assembly (I don't have the source code of that assembly, I reflected the file to view the code) someone had written this:
Amount = Convert.ToSingle(10219150); //the value from the stored procedure
So, when I invoke that method which does the final conversion, it returns this value:
1.021315E+7
How is that possible? Why does the Convert.ToSingle add extra decimal positions? I don't understand.
Is there a way that i can reverse that conversion on my code when I invoke that method of the assembly? I can't rewrite that assembly file as it's too big, and, as I mentioned earlier, I don't have the source code to fix the conversion.
From this: 1.021315E+7 To this: 10219150 again (restore the correct value without that conversion)
Hope I made myself clear.
Thanks in advance.
The conversion to single isn't adding extra precision.
10219150 is 1.021315E+7 (which is just another way of writing 1.021315 * 107).
The method you are using to print out the value is just using scientific notation to display the number.
If you are printing the number then you need to set the formatting options.
float amount = Convert.ToSingle("10219150");
string toPrint = string.Format("{0:N}", amount);
Will print the number as:
"10,219,150.00"
To get no decimal places use "{0:N0}" as the format string.
You have two issues. One is easily solved, and the other may be more difficult or impossible.
As ChrisF stated, 1.021315E+7 is simply another way of writing 10219150. (The E+7 part in Scientific Notation means to shift the decimal point 7 places to the right.) When you format your single precision value, you can use
fvalue.ToString("f0");
to display as an integer, rather than in Scientific Notation.
The bigger problem, unfortunately, is that a single precision float can only hold 7 significant digits, and in your example you are storing 8. Therefore, the last digit may be rounded. (Since it happens to be 0 in your case, the rounding might not have been noticed.)
If that loss of precision is critical, you would likely need to fetch the value from the database as a long, or as a double-precision value (depending on the type of data returned.) Each of these types can hold more significant digits.
When the value is converted to Single, it's rounded as it contains more significant digits that can fit in a Single. If you convert 10213153 to Single you also end up with 1.021315E+7 i.e. 10213150.
As the code uses a Single to store the amount, there is nothing that you can do to make it handle the current value correctly. The amount simply can not be represented correctly as a Single.
You either have to use lower values, or change the code.
I'm working with an XML file that subscribes to an industry standard. The standards document for the schema defines one of the fields as a rational number and its data is represented as two integers, typically with the second value being a 1 (e.g. <foo>20 1</foo>). I've been hunting around without a great deal of success to see if there's an XML-defined standard for rational numbers. I did find this (8 year old) exchange on the mailing list for XML-SCHEMA:
http://markmail.org/message/znvfw2r3a2pfeykl
I'm not clear that there is a standard "XML way" for representing rational numbers and whether the standard applying to this document is subscribing to it, or whether they've cooked up their own way of doing it for their documents and are relying on people to read the standard. The document is not specific beyond saying the field is a rational number.
Assuming there is a standard way of representing rational numbers and this document is correctly implementing it, does the functionality in System.Xml recognize it? Again, my searches have not been particularly fruitful.
Thanks for any feedback anyone has.
This isn't exactly an answer to the XML-side of things, but if you are wanting a C# class for representing rational numbers, I write a very flexible one a while back as part of my ExifUtils library (since most EXIF values are represented as rational numbers).
Rational<T> https://github.com/mckamey/exif-utils.net/blob/master/ExifUtils/ExifUtils/Rational.cs
The class itself is generic accepting a numerator/denominator of any type implementing IConvertable (which includes all BCL number types) and will serialize (ToString) and deserialize (Parse/TryParse) which may give you exactly what you need for your XML representation.
If you absolutely must represent a rational number with a space, you could adapt it to use space ' ' as the delimiter with literally a single character change in the source.
As a slightly off-topic aside in response to Steven Lowe's comments, the use of rational numbers while seemingly unintuitive has some advantages. Numbers such as PI cannot be represented as a decimal/floating point number either. The approximation of PI (e.g. the value in Math.PI) can be just as precisely represented as a rational number:
314159265358979323846 / 100000000000000000000
Whereas the very simple rational number 2/3 is impossible to represent to the same precision as any sort of floating point / fixed precision decimal number:
0.66666666666666666667
i'm glad they didn't accept this proposal as a standard! the guy proposing to base all other numbers on a 'rational number' primitive has never heard of transcendental numbers (like Pi, for example) which cannot be represented in this manner
but back to your question - i've only run across rational numbers in xml as part of an RDF specification for certain engineering values related to the power industry. I think it was just a pair of numbers separated by a comma
this document defines the format as N/M, while another reference has it as N,M
You can express fractions in MathML. That is the industry standard AFAIK.