Get Time
Search | Watch Thread  |  My Post History  |  My Watches  |  User Settings
View: Flat (newest first)  | Threaded  | Tree
Previous Thread  |  Next Thread
Recipe rewrite: Choosing correct (numeric) data types | Reply
Problem: You want your numeric calculation behave as expected.
Solution: Choosing correct data types to prevent overflow and precision errors. When in doubt, as the rule of thumb, for integer number calculation, use “long” instead of “int” to prevent overflow, and for real number calculation, consider using “double” to prevent precision errors.
Discussion: You need to know the way your programming language of choice handle numeric calculation because each language has it own default rules. Furthermore, a general knowledge about valid ranges of numeric data types is also helpful.

Example 1: Problem “FeudaliasBattle on Single Round Match 438 Round 1 - Division II, Level Two” requires calculation the distance between 2 points (x1, y1) and (x2, y2). Below is a possible method to do the calculation:
double d(int x1, int y1, int x2, int y2){
  return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));

From the problem statement, x1, y1, x2 and y2 can range from 0 and 1,000,000. So (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) may produces results larger than maximum int value (about 2 billions) with extreme test cases. This causes overflows and hence, lead to incorrect results . A correct solution is to cast x1, y1, x2, and y2 to long manually like:
double d(int x1, int y1, int x2, int y2){
  long lx1 = x1, ly1 = y1, lx2 = x2, ly2 = y2;
  return Math.sqrt((lx1-lx2)*(lx1-lx2) + (ly1-ly2)*(ly1-ly2));

Example 2: Assume you have 2 integers x and y (and assume y does not equals to zero). You want to get a real number z which is the result of dividing x by y. You may do this with:
z = x/y;

but in C++/Java/C# languages, x/y, which x and y are both integers, always produce an integer. So z is not the real result expected. To get the expected result, you need to manually cast x or y to real value first, like:
z = (double)x/y;

or you can let your programming language cast it for you automatically by including a real number to the expression, like:
z = 1.0*x/y;

z = (x-0.0)/y;

See also: Testing for Correctness
Re: Recipe rewrite: Choosing correct (numeric) data types (response to post by dttri) | Reply
Weird, the rewritten recipe somehow looks worse than the original one. You've lost "General tips" which are very basic but still good (though I'd write boundary values as 2*109 to avoid many hard-to-count zeros). Original "Problem" was better than the current one. Also you've used none of the good tips you were given in the original thread.

Overall the recipe needs more content: examples, tips and discussion, including language-specific things. For example, you can mention that Java has no "unsigned" types, but as reference solutions to all problems are written in Java, you won't really need these types to solve the problem.