In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly analyzes the causes of the precision problem of iOS floating-point type and the relevant knowledge about what the solution is. The content is detailed and easy to understand, and the operation details are reasonable, so it has a certain reference value. If you are interested, you might as well follow the editor to take a look, and follow the editor to learn more about the cause and solution of the iOS floating-point type precision problem.
Preface
I believe that many people (in fact, I think it should be everyone) have encountered a problem, that is, when decimals appear in the JSON data returned by the server, there will always be a loss of precision when the client uses CGFloat to parse, especially when it comes to sensitive data, this loss of precision can not be tolerated at all. The following will start from a simple solution and principle. Let's take you to review this small problem that we have all learned before but have almost forgotten.
How to solve the floating-point precision problem rounding processing / / for example, the server returns such a json {"price": 1.9} / / the client parses the price and prints 1.9CGFloat price = model.priceNSLog (@ "% f", price). The result is 1.89999999999999999.
At this time, as a salted fish developer, you can write the following code:
NSLog (@ "% .2f", price) output: 1.89max / inaccurate, it doesn't matter, there is a way to NSLog (@ "f% @", round (price*10) / 10); output 1.9
Of course, the NSDecimalNumber type provided by apple specifically for precision problems can also solve this problem. The use of NSDecimalNumber is very simple. As for how simple, please do your own Baidu, don't ask me, I can't write it without Baidu.
Better solution
So the question is, as a salted fish who is too lazy to write for a whole year, which way should I choose to solve this problem?
All right, here comes the big show, next, let's code!
/ / the server must return a string type. If the server does not do so: * * Please go to the back-end developer with a hammer and gas tank to solve the problem * * @ property (nonatomic,copy) NSString * price
Yes, I will choose not to solve this problem and kick the ball out. This is what a qualified developer should do.
Reasons for loss of accuracy
Solving the problem of floating-point precision is one aspect, but such a simple content is not enough for me to finish a whole article, so next, let's talk about why the numbers are well parsed, why is it not accurate?
Many people may be able to say that the loss of precision is due to the storage of floating-point numbers. after all, professional counterparts have learned it at school, but they touch their little heads. Hey, is it the same as me? Forget all about it?
And since there are always some basic interviewers and pretending interviewers who have just reviewed this part of the content, they like to pick these small questions to make things difficult for us elderly fish-touching programmers, so let's review this part of the knowledge.
How floating-point types are stored
The way floating-point types are stored in a computer is in the form of scientific counting:
For example, scientific counting represents the decimal 90.9 = > 9.09 x 10 ^ 18.3 = > 8.3 x 10 ^ 0
If we want to store 8.3 (8.3 x 10 ^ 0), we must first convert 8.3 to binary, and when 8 is converted to binary, what about 1000?
Old programmer, do you suddenly find that you have forgotten how decimals are converted into binary? put down your trembling hands ready for Baidu. I have everything you want!
Take 0.9 as an example, multiply 0.9 by 2, the integer part of the number is the first decimal place in binary, take out the decimal part of the result part and multiply it by 2, take the integer part as the second place, and repeat the above operation over and over again. Until the result equals 0 or there is a loop.
0. 9 * 2 = 1. 8 bit 10. 8 * 2 = 1. 6 bit 10. 6 * 2 = 1.2 3 bit 10. 2 * 2 = 0. 4 bit 0. 4 * 2 = 0. 8 bit 0. 8 * 2 = 1. 6 bit 1 has a cycle, then the binary of 0.9 is 0.1 1100 1100 1100. Among them, 1100 infinite loops
After reviewing above, we know that the binary system of 8.3 can be expressed as 1000.0 1001 1001 1001. (1001 infinite loop) expressed by scientific counting, 1.000 1001 1001 1001 x 2 ^ 3
Integer part index part decimal part 13.000 0 1001 1001 1001
We know that float is 4 (32-bit) bytes, and each bit is allocated as follows when storing.
31 symbol bit 23-30 (exponential) 0-22 (decimal) 13.000 1001 1001 1001 significant digits
You can see that there are 23 digits in the Mantissa part, but since any number after the Science and Technology Law can be expressed in the form of 1.aaa x 2 ^ b, 1 can be omitted. (at this time, someone is going to argue, why? what are we going to do with 0.aaa x 2 ^ b? Answer: B can be negative), so the number of digits that a total of 23 digits can actually express is actually 24 digits.
The maximum number that can be expressed in 24 bits is 16777215, which cannot be accurately expressed if it is greater than this number.
Of course, an uncertainty greater than 16777215 cannot be accurately expressed at all, such as 16777216, whose binary expression is 1 followed by a heap of 0. Because it is the integer power of 2, then there are all zeros behind it, so the 23 bits can store the number, but not if there is 1 after the 23 bit 0, and so on, there will be a number after 16777215 that can meet the condition of the integer power of 2, and can also be expressed correctly.
Although some numbers greater than 16777215 can be accurately expressed, we must be accurate when we talk about accuracy, then the number that can be accurately expressed is only between 0 and 16777215. Between 16777215, let's count a total of 8 digits. However, because the highest bit 1 can not be fully included at the beginning, so the accuracy should be 7 significant digits.
In addition, I would like to mention the expression range of floating point numbers. This range must be determined by the index. I don't care how much it is. If you are interested, you can calculate it.
Index storage: shift storage
You can see that the index part gives a total of 8 bit bits, because the index is positive or negative, so assuming that our first bit represents the symbol bit, then the number range that we can represent is-127127 ~ + 127s.
Then the expressible range is divided into two parts:
1 0 ~ 1 111111 1 = >-0 to-000000
0 0 ~ 0 111111 1 = > + 0 to 000000
Obviously, if there is a-0 and a + 0, shift storage occurs to avoid this problem: that is, if the highest bit is not used to represent symbol bits, the range of 8 bit can be 0-255. let's re-plan the next two intervals:
00000000-01111111 = > 0127minus 127indicates the number before
10000000-11111111 = > 128,256minus 127indicates the number before 1127.
In this way, the problem of +-0 is avoided. After the 8.3 is converted to a decimal, the index position is 3, so the actual storage time of 3 is 10000010. Let's update the actual stored table.
Bit 31 symbol bit 23-30 (exponential) 0-22 (decimal) 110000010.000 0 1001 1001 1001double type
The double type is 8 bytes and 64 bits. Only the number of bits represented by the double is different from that of float, and everything else is the same. The number of bits represented by double precision is as follows:
63 symbol bit 52-62 (exponential) 0-51 (decimal) Summary: reasons for loss of accuracy of output results
Back to the original 1.9, the number was printed as 1.8999999999999999, and now we should know why, because 1.9 to binary is an infinite loop, and the latter part of the loop is intercepted only 23 digits due to storage. The restored decimal number must not be the same as before. By the same token, if the decimal point is followed by a decimal point of .5, a multiple of 5, the printed decimal is generally normal, because .5 to binary is not an infinite loop.
This is the end of the introduction on "what are the causes and solutions to the precision problem of iOS floating-point types". More related content can be searched for previous articles, hoping to help you answer questions and questions, please support the website!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.