Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Поговорим про арифметику

119,432 views

Published on

Программисты часто работают с числами. Чаще всего это целые числа, но иногда доводится работать и с дробными. C этими самыми числами приходится делать разные операции: сложение, умножение, приведение типов, сравнение, округление и многие другие. Увы, далеко не все до конца понимают, как же именно компьютер совершает все эти замечательные операции. В этом докладе мы с вами прорешаем серию увлекательных упражнений на знание арифметики. Поговорим про стандарт IEEE 754, про разницу в рантаймах и компиляторах, про регистры FPU и прочие сложности жизни.

Published in: Technology
  • Be the first to comment

Поговорим про арифметику

  1. 1. Поговорим про арифметику Андрей Акиньшин, JetBrains DotNext 2016 SPb 1/32
  2. 2. Про что будем разговаривать? 2/32
  3. 3. Упражнение №1 Задача. Что выведет следующий код? Write(0.1 + 0.2 == 0.3); 3/32
  4. 4. Упражнение №1 Задача. Что выведет следующий код? Write(0.1 + 0.2 == 0.3); A true 3/32
  5. 5. Упражнение №1 Задача. Что выведет следующий код? Write(0.1 + 0.2 == 0.3); A true B false 3/32
  6. 6. Упражнение №1 Задача. Что выведет следующий код? Write(0.1 + 0.2 == 0.3); A true B false C 0.3 3/32
  7. 7. Упражнение №1 Задача. Что выведет следующий код? Write(0.1 + 0.2 == 0.3); A true B false C 0.3 D ArithmeticException 3/32
  8. 8. Упражнение №1 Задача. Что выведет следующий код? Write(0.1 + 0.2 == 0.3); A true BB false C 0.3 D ArithmeticException 3/32
  9. 9. [Решение] Упражнение №1 0.1d ≈ 0.100000000000000005551115123125783 4/32
  10. 10. [Решение] Упражнение №1 0.1d ≈ 0.100000000000000005551115123125783 +0.2d ≈ 0.200000000000000011102230246251565 4/32
  11. 11. [Решение] Упражнение №1 0.1d ≈ 0.100000000000000005551115123125783 +0.2d ≈ 0.200000000000000011102230246251565 0.300000000000000044408920985006262 4/32
  12. 12. [Решение] Упражнение №1 0.1d ≈ 0.100000000000000005551115123125783 +0.2d ≈ 0.200000000000000011102230246251565 0.300000000000000044408920985006262 0.3d ≈ 0.299999999999999988897769753748435 4/32
  13. 13. [Решение] Упражнение №1 0.1d ≈ 0.100000000000000005551115123125783 +0.2d ≈ 0.200000000000000011102230246251565 0.300000000000000044408920985006262 0.3d ≈ 0.299999999999999988897769753748435 Вывод: 0.1d + 0.2d = 0.3d 4/32
  14. 14. Упражнение №2 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); GC.KeepAlive(y); } 5/32
  15. 15. Упражнение №2 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); GC.KeepAlive(y); } A true 5/32
  16. 16. Упражнение №2 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); GC.KeepAlive(y); } A true B false 5/32
  17. 17. Упражнение №2 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); GC.KeepAlive(y); } A true B false C ArithmeticException 5/32
  18. 18. Упражнение №2 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); GC.KeepAlive(y); } A true B false C ArithmeticException D Зависит 5/32
  19. 19. Упражнение №2 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); GC.KeepAlive(y); } AA true B false C ArithmeticException D Зависит 5/32
  20. 20. Упражнение №3 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); // GC.KeepAlive(y); } 6/32
  21. 21. Упражнение №3 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); // GC.KeepAlive(y); } A true 6/32
  22. 22. Упражнение №3 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); // GC.KeepAlive(y); } A true B false 6/32
  23. 23. Упражнение №3 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); // GC.KeepAlive(y); } A true B false C ArithmeticException 6/32
  24. 24. Упражнение №3 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); // GC.KeepAlive(y); } A true B false C ArithmeticException D Зависит 6/32
  25. 25. Упражнение №3 Задача. Что выведет следующий код? float Sum(float a, float b) => a + b; float x; void Main() { x = Sum(0.1f, 0.2f); float y = Sum(0.1f, 0.2f); Write(x == y); // GC.KeepAlive(y); } A true B false C ArithmeticException DD Зависит 6/32
  26. 26. [Решение] Упражнение №3 Ответ. Debug Release MS.NET true false Mono true true 7/32
  27. 27. [Решение] Упражнение №3 Ответ. Debug Release MS.NET true false Mono true true Объяснение. ECMA-335, I.12.1.3 “Handling of floating-point data types” “The nominal type of the variable or expression is either float32 or float64, but its value can be represented internally with additional range and/or precision.” 7/32
  28. 28. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. 8/32
  29. 29. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. A int value1 = (int)(6.2f * 10); 8/32
  30. 30. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. A int value1 = (int)(6.2f * 10); B float mul = 6.2f * 10; int value2 = (int)mul; 8/32
  31. 31. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. A int value1 = (int)(6.2f * 10); B float mul = 6.2f * 10; int value2 = (int)mul; C A и B правильные 8/32
  32. 32. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. A int value1 = (int)(6.2f * 10); B float mul = 6.2f * 10; int value2 = (int)mul; C A и B правильные D A и B неправильные 8/32
  33. 33. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. A int value1 = (int)(6.2f * 10); BB float mul = 6.2f * 10; int value2 = (int)mul; C A и B правильные D A и B неправильные 8/32
  34. 34. Упражнение №4 Задача. Умножить 6.2f на 10, результат вернуть в виде int. Получить 62. A int value1 = (int)(6.2f * 10); BB float mul = 6.2f * 10; int value2 = (int)mul; C A и B правильные D A и B неправильные Проверка решения. mcs 4.2.3 MSBuild/12.0/Bin/csc.exe Roslyn 1.0.0–1.1.1 Roslyn 1.2.0+ A value1 61 62 B value2 62 62 8/32
  35. 35. [Решение] Упражнение №4 double d = 6.2f * 10d; // d = 61.9999980926513671875 float f = RoundToFloat(d); // f = 62 int i1 = TruncToInt(d); // i = 61 int i2 = TruncToInt(f); // i = 62 9/32
  36. 36. [Решение] Упражнение №4 double d = 6.2f * 10d; // d = 61.9999980926513671875 float f = RoundToFloat(d); // f = 62 int i1 = TruncToInt(d); // i = 61 int i2 = TruncToInt(f); // i = 62 int value1 = (int)(6.2f * 10); // IL_0000: ldc.i4.s 61 or 62 ; int // IL_0002: stloc.0 9/32
  37. 37. [Решение] Упражнение №4 double d = 6.2f * 10d; // d = 61.9999980926513671875 float f = RoundToFloat(d); // f = 62 int i1 = TruncToInt(d); // i = 61 int i2 = TruncToInt(f); // i = 62 int value1 = (int)(6.2f * 10); // IL_0000: ldc.i4.s 61 or 62 ; int // IL_0002: stloc.0 float mul = 6.2f * 10; int value2 = (int)mul; // IL_0003: ldc.r4 62 ; float // IL_0008: conv.i4 // IL_0009: ldloc.0 9/32
  38. 38. Упражнение №5 Задача. Вычислите следующие величины: Math.Round(-0.5), Math.Round(-1.5) 10/32
  39. 39. Упражнение №5 Задача. Вычислите следующие величины: Math.Round(-0.5), Math.Round(-1.5) A Round(-0.5) = 0 Round(-1.5) = -1 10/32
  40. 40. Упражнение №5 Задача. Вычислите следующие величины: Math.Round(-0.5), Math.Round(-1.5) A Round(-0.5) = 0 Round(-1.5) = -1 B Round(-0.5) = -1 Round(-1.5) = -2 10/32
  41. 41. Упражнение №5 Задача. Вычислите следующие величины: Math.Round(-0.5), Math.Round(-1.5) A Round(-0.5) = 0 Round(-1.5) = -1 B Round(-0.5) = -1 Round(-1.5) = -2 C Round(-0.5) = 0 Round(-1.5) = -2 10/32
  42. 42. Упражнение №5 Задача. Вычислите следующие величины: Math.Round(-0.5), Math.Round(-1.5) A Round(-0.5) = 0 Round(-1.5) = -1 B Round(-0.5) = -1 Round(-1.5) = -2 C Round(-0.5) = 0 Round(-1.5) = -2 D Round(-0.5) = -1 Round(-1.5) = -1 10/32
  43. 43. Упражнение №5 Задача. Вычислите следующие величины: Math.Round(-0.5), Math.Round(-1.5) A Round(-0.5) = 0 Round(-1.5) = -1 B Round(-0.5) = -1 Round(-1.5) = -2 CC Round(-0.5) = 0 Round(-1.5) = -2 D Round(-0.5) = -1 Round(-1.5) = -1 10/32
  44. 44. [Решение] Упражнение №5 enum MidpointRounding { AwayFromZero, // Прочь от нуля ToEven // К ближайшему чётному } 11/32
  45. 45. [Решение] Упражнение №5 enum MidpointRounding { AwayFromZero, // Прочь от нуля ToEven // К ближайшему чётному } static double Round( double value, MidpointRounding mode ) static double Round( double value ) // mode = ToEven 11/32
  46. 46. [Решение] Упражнение №5 enum MidpointRounding { AwayFromZero, // Прочь от нуля ToEven // К ближайшему чётному } static double Round( double value, MidpointRounding mode ) static double Round( double value ) // mode = ToEven Round(-0.5) = 0 Round(-1.5) = -2 11/32
  47. 47. Упражнение №6 Задача. Что выведет следующий код? int x = 2147483584; Write((int)(float)x); 12/32
  48. 48. Упражнение №6 Задача. Что выведет следующий код? int x = 2147483584; Write((int)(float)x); A 2147483584 12/32
  49. 49. Упражнение №6 Задача. Что выведет следующий код? int x = 2147483584; Write((int)(float)x); A 2147483584 B 2147483647 (int.MaxValue) 12/32
  50. 50. Упражнение №6 Задача. Что выведет следующий код? int x = 2147483584; Write((int)(float)x); A 2147483584 B 2147483647 (int.MaxValue) C -2147483648 (int.MinValue) 12/32
  51. 51. Упражнение №6 Задача. Что выведет следующий код? int x = 2147483584; Write((int)(float)x); A 2147483584 B 2147483647 (int.MaxValue) C -2147483648 (int.MinValue) D OverflowException 12/32
  52. 52. Упражнение №6 Задача. Что выведет следующий код? int x = 2147483584; Write((int)(float)x); A 2147483584 B 2147483647 (int.MaxValue) CC -2147483648 (int.MinValue) DD OverflowException 12/32
  53. 53. [Решение] Упражнение №6 unchecked { Write((int)(float)x); } ⇓ x = 2147483584 (float)x = 2147483648 = +231 (int)(float)x = -2147483648 = −231 13/32
  54. 54. [Решение] Упражнение №6 unchecked { Write((int)(float)x); } ⇓ x = 2147483584 (float)x = 2147483648 = +231 (int)(float)x = -2147483648 = −231 checked { Write((int)(float)x); } ⇓ OverflowException 13/32
  55. 55. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); 14/32
  56. 56. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); A 0 14/32
  57. 57. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); A 0 B 1 14/32
  58. 58. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); A 0 B 1 C -2147483648 (int.MinValue) 14/32
  59. 59. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); A 0 B 1 C -2147483648 (int.MinValue) D OverflowException 14/32
  60. 60. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); A 0 BB 1 C -2147483648 (int.MinValue) D OverflowException 14/32
  61. 61. Упражнение №7 Задача. Что выведет следующий код? Write(1 << 32); A 0 BB 1 C -2147483648 (int.MinValue) D OverflowException ECMA-334, 14.8 “Shift operators” “When the type of x is int or uint, the shift count is given by the low-order five bits of count.” int x: (x 0) = (x 32) = (x 64) = . . . long x: (x 0) = (x 64) = (x 128) = . . . 14/32
  62. 62. Упражнение №8 Задача. Выпишите таблицу истинности для следующих nullable-операций: Write(false | null); Write(true | null); Write(false & null); Write(true & null); Write(false ^ null); Write(true ^ null); 15/32
  63. 63. Упражнение №8 Задача. Выпишите таблицу истинности для следующих nullable-операций: Write(false | null); Write(true | null); Write(false & null); Write(true & null); Write(false ^ null); Write(true ^ null); A Код не скомпилируется 15/32
  64. 64. Упражнение №8 Задача. Выпишите таблицу истинности для следующих nullable-операций: Write(false | null); Write(true | null); Write(false & null); Write(true & null); Write(false ^ null); Write(true ^ null); A Код не скомпилируется B Все выражения вернут null 15/32
  65. 65. Упражнение №8 Задача. Выпишите таблицу истинности для следующих nullable-операций: Write(false | null); Write(true | null); Write(false & null); Write(true & null); Write(false ^ null); Write(true ^ null); A Код не скомпилируется B Все выражения вернут null C ArithmeticException 15/32
  66. 66. Упражнение №8 Задача. Выпишите таблицу истинности для следующих nullable-операций: Write(false | null); Write(true | null); Write(false & null); Write(true & null); Write(false ^ null); Write(true ^ null); A Код не скомпилируется B Все выражения вернут null C ArithmeticException D Другое 15/32
  67. 67. Упражнение №8 Задача. Выпишите таблицу истинности для следующих nullable-операций: Write(false | null); Write(true | null); Write(false & null); Write(true & null); Write(false ^ null); Write(true ^ null); A Код не скомпилируется B Все выражения вернут null C ArithmeticException DD Другое 15/32
  68. 68. [Решение] Упражнение №8 ECMA-334, 14.10.4 “The bool? logical operators” В стандарте приводятся таблицы, из которых явно следует: | null & null ^ null false null false null true true null null 16/32
  69. 69. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; 17/32
  70. 70. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; A x (Нет такого x) 17/32
  71. 71. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; A x (Нет такого x) B x = +∞ (double.PositiveInfinity) 17/32
  72. 72. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; A x (Нет такого x) B x = +∞ (double.PositiveInfinity) C x = −∞ (double.NegativeInfinity) 17/32
  73. 73. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; A x (Нет такого x) B x = +∞ (double.PositiveInfinity) C x = −∞ (double.NegativeInfinity) D x /∈ R (double.NaN) 17/32
  74. 74. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; A x (Нет такого x) B x = +∞ (double.PositiveInfinity) C x = −∞ (double.NegativeInfinity) DD x /∈ R (double.NaN) 17/32
  75. 75. Упражнение №9 Задача. Найдите такое x, для которого функция Check вернёт false. bool Check(double x) => x == x; A x (Нет такого x) B x = +∞ (double.PositiveInfinity) C x = −∞ (double.NegativeInfinity) DD x /∈ R (double.NaN) ECMA-334, 14.9.2 “Floating-point comparison operators” If either operand is NaN, the result is false for all operators except !=, for which the result is true. 17/32
  76. 76. Упражнение №10 Задача. Что выведет следующий код? double x = double.NaN; Write(x == 1.0); 18/32
  77. 77. Упражнение №10 Задача. Что выведет следующий код? double x = double.NaN; Write(x == 1.0); A false 18/32
  78. 78. Упражнение №10 Задача. Что выведет следующий код? double x = double.NaN; Write(x == 1.0); A false B true 18/32
  79. 79. Упражнение №10 Задача. Что выведет следующий код? double x = double.NaN; Write(x == 1.0); A false B true C double.NaN 18/32
  80. 80. Упражнение №10 Задача. Что выведет следующий код? double x = double.NaN; Write(x == 1.0); A false B true C double.NaN D OverflowException 18/32
  81. 81. Упражнение №10 Задача. Что выведет следующий код? double x = double.NaN; Write(x == 1.0); AA false B true C double.NaN DD OverflowException 18/32
  82. 82. [Решение] Упражнение №10 .NET 027F 0000 0010 0111 1111 Delphi 1272 0001 0010 0111 0010 19/32
  83. 83. Упражнение №11 Задача. Найдите такое x для которого функции Negate1 и Negate2 вернут разные значения. string Binary(double x) => string.Format( "{0:X16}", BitConverter.DoubleToInt64Bits(x)); string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); 20/32
  84. 84. Упражнение №11 Задача. Найдите такое x для которого функции Negate1 и Negate2 вернут разные значения. string Binary(double x) => string.Format( "{0:X16}", BitConverter.DoubleToInt64Bits(x)); string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); A x (Нет такого x) 20/32
  85. 85. Упражнение №11 Задача. Найдите такое x для которого функции Negate1 и Negate2 вернут разные значения. string Binary(double x) => string.Format( "{0:X16}", BitConverter.DoubleToInt64Bits(x)); string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); A x (Нет такого x) B 0 (0) 20/32
  86. 86. Упражнение №11 Задача. Найдите такое x для которого функции Negate1 и Negate2 вернут разные значения. string Binary(double x) => string.Format( "{0:X16}", BitConverter.DoubleToInt64Bits(x)); string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); A x (Нет такого x) B 0 (0) C x /∈ R (double.NaN) 20/32
  87. 87. Упражнение №11 Задача. Найдите такое x для которого функции Negate1 и Negate2 вернут разные значения. string Binary(double x) => string.Format( "{0:X16}", BitConverter.DoubleToInt64Bits(x)); string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); A x (Нет такого x) B 0 (0) C x /∈ R (double.NaN) D x ≈ 1.79769 · 10308 (double.MaxValue) 20/32
  88. 88. Упражнение №11 Задача. Найдите такое x для которого функции Negate1 и Negate2 вернут разные значения. string Binary(double x) => string.Format( "{0:X16}", BitConverter.DoubleToInt64Bits(x)); string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); A x (Нет такого x) BB 0 (0) CC x /∈ R (double.NaN) D x ≈ 1.79769 · 10308 (double.MaxValue) 20/32
  89. 89. [Решение] Упражнение №11 string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); 21/32
  90. 90. [Решение] Упражнение №11 string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); Binary(0) == "0000000000000000" // +0.0 Negate1(0) == "8000000000000000" // -0.0 Negate2(0) == "0000000000000000" // +0.0 21/32
  91. 91. [Решение] Упражнение №11 string Negate1(double x) => Binary( -x); string Negate2(double x) => Binary(0-x); Binary(0) == "0000000000000000" // +0.0 Negate1(0) == "8000000000000000" // -0.0 Negate2(0) == "0000000000000000" // +0.0 Binary(double.NaN) == "FFF8000000000000" Negate1(double.NaN) == "7FF8000000000000" Negate2(double.NaN) == "FFF8000000000000" 21/32
  92. 92. Упражнение №12 Задача. Что выведет следующий код? struct DoubleInt { public double X; public int Y; } var a = new DoubleInt { X = +0.0 }; var b = new DoubleInt { X = -0.0 }; Write(a.Equals(b)); 22/32
  93. 93. Упражнение №12 Задача. Что выведет следующий код? struct DoubleInt { public double X; public int Y; } var a = new DoubleInt { X = +0.0 }; var b = new DoubleInt { X = -0.0 }; Write(a.Equals(b)); A true 22/32
  94. 94. Упражнение №12 Задача. Что выведет следующий код? struct DoubleInt { public double X; public int Y; } var a = new DoubleInt { X = +0.0 }; var b = new DoubleInt { X = -0.0 }; Write(a.Equals(b)); A true B false 22/32
  95. 95. Упражнение №12 Задача. Что выведет следующий код? struct DoubleInt { public double X; public int Y; } var a = new DoubleInt { X = +0.0 }; var b = new DoubleInt { X = -0.0 }; Write(a.Equals(b)); A true B false C double.NaN 22/32
  96. 96. Упражнение №12 Задача. Что выведет следующий код? struct DoubleInt { public double X; public int Y; } var a = new DoubleInt { X = +0.0 }; var b = new DoubleInt { X = -0.0 }; Write(a.Equals(b)); A true B false C double.NaN D Зависит 22/32
  97. 97. Упражнение №12 Задача. Что выведет следующий код? struct DoubleInt { public double X; public int Y; } var a = new DoubleInt { X = +0.0 }; var b = new DoubleInt { X = -0.0 }; Write(a.Equals(b)); AA true B false C double.NaN D Зависит 22/32
  98. 98. Упражнение №13 Задача. Что выведет следующий код? struct DoubleDouble { public double X; public double Y; } var a = new DoubleDouble { X = +0.0 }; var b = new DoubleDouble { X = -0.0 }; Write(a.Equals(b)); 23/32
  99. 99. Упражнение №13 Задача. Что выведет следующий код? struct DoubleDouble { public double X; public double Y; } var a = new DoubleDouble { X = +0.0 }; var b = new DoubleDouble { X = -0.0 }; Write(a.Equals(b)); A true 23/32
  100. 100. Упражнение №13 Задача. Что выведет следующий код? struct DoubleDouble { public double X; public double Y; } var a = new DoubleDouble { X = +0.0 }; var b = new DoubleDouble { X = -0.0 }; Write(a.Equals(b)); A true B false 23/32
  101. 101. Упражнение №13 Задача. Что выведет следующий код? struct DoubleDouble { public double X; public double Y; } var a = new DoubleDouble { X = +0.0 }; var b = new DoubleDouble { X = -0.0 }; Write(a.Equals(b)); A true B false C double.NaN 23/32
  102. 102. Упражнение №13 Задача. Что выведет следующий код? struct DoubleDouble { public double X; public double Y; } var a = new DoubleDouble { X = +0.0 }; var b = new DoubleDouble { X = -0.0 }; Write(a.Equals(b)); A true B false C double.NaN D Зависит 23/32
  103. 103. Упражнение №13 Задача. Что выведет следующий код? struct DoubleDouble { public double X; public double Y; } var a = new DoubleDouble { X = +0.0 }; var b = new DoubleDouble { X = -0.0 }; Write(a.Equals(b)); A true B false C double.NaN DD Зависит 23/32
  104. 104. [Решение] Упражнение №13 DoubleInt DoubleDouble MS.NET true false Mono true true 24/32
  105. 105. [Решение] Упражнение №13 DoubleInt DoubleDouble MS.NET true false Mono true true // MS.NET class ValueType { bool Equals (Object obj) { // ... if (CanCompareBits(this)) return FastEqualsCheck(thisObj, obj); // ... } // Проверяем, что структура "tightly packed" static extern bool CanCompareBits(Object obj); } 24/32
  106. 106. Упражнение №14 Задача. Найдите три таких числа a, b, c типа double (не равных double.NaN), чтобы для них выполнилось нижеприведённое неравенство. (a + b) + c = a + (b + c) 25/32
  107. 107. Упражнение №14 Задача. Найдите три таких числа a, b, c типа double (не равных double.NaN), чтобы для них выполнилось нижеприведённое неравенство. (a + b) + c = a + (b + c) A (a, b, c) (Нет таких чисел) 25/32
  108. 108. Упражнение №14 Задача. Найдите три таких числа a, b, c типа double (не равных double.NaN), чтобы для них выполнилось нижеприведённое неравенство. (a + b) + c = a + (b + c) A (a, b, c) (Нет таких чисел) B a = 10100 , b = 10100 , c = 1 25/32
  109. 109. Упражнение №14 Задача. Найдите три таких числа a, b, c типа double (не равных double.NaN), чтобы для них выполнилось нижеприведённое неравенство. (a + b) + c = a + (b + c) A (a, b, c) (Нет таких чисел) B a = 10100 , b = 10100 , c = 1 C a = 10100 , b = −10100 , c = 1 25/32
  110. 110. Упражнение №14 Задача. Найдите три таких числа a, b, c типа double (не равных double.NaN), чтобы для них выполнилось нижеприведённое неравенство. (a + b) + c = a + (b + c) A (a, b, c) (Нет таких чисел) B a = 10100 , b = 10100 , c = 1 C a = 10100 , b = −10100 , c = 1 D a = 10100 , b = 10−100 , c = 1 25/32
  111. 111. Упражнение №14 Задача. Найдите три таких числа a, b, c типа double (не равных double.NaN), чтобы для них выполнилось нижеприведённое неравенство. (a + b) + c = a + (b + c) A (a, b, c) (Нет таких чисел) B a = 10100 , b = 10100 , c = 1 CC a = 10100 , b = −10100 , c = 1 D a = 10100 , b = 10−100 , c = 1 25/32
  112. 112. [Решение] Упражнение №14 double a = 1e100, b = -1e100, c = 1; 26/32
  113. 113. [Решение] Упражнение №14 double a = 1e100, b = -1e100, c = 1; (a + b) + c = (10100 − 10100 ) + 1 = 0 + 1 = 1 26/32
  114. 114. [Решение] Упражнение №14 double a = 1e100, b = -1e100, c = 1; (a + b) + c = (10100 − 10100 ) + 1 = 0 + 1 = 1 a+(b+c) = 10100 +(−10100 +1) = 10100 −10100 = 0 26/32
  115. 115. Упражнение №15 Задача. Что выведет следующий код?1 Write("{0:N30}", 24m * 22m / 24m); 1 Постфикс m означает тип decimal 27/32
  116. 116. Упражнение №15 Задача. Что выведет следующий код?1 Write("{0:N30}", 24m * 22m / 24m); A 22.000000000000000000000000000000 1 Постфикс m означает тип decimal 27/32
  117. 117. Упражнение №15 Задача. Что выведет следующий код?1 Write("{0:N30}", 24m * 22m / 24m); A 22.000000000000000000000000000000 B 22.000000000000000000000000001000 1 Постфикс m означает тип decimal 27/32
  118. 118. Упражнение №15 Задача. Что выведет следующий код?1 Write("{0:N30}", 24m * 22m / 24m); A 22.000000000000000000000000000000 B 22.000000000000000000000000001000 C 24.000000000000000000000000000000 1 Постфикс m означает тип decimal 27/32
  119. 119. Упражнение №15 Задача. Что выведет следующий код?1 Write("{0:N30}", 24m * 22m / 24m); A 22.000000000000000000000000000000 B 22.000000000000000000000000001000 C 24.000000000000000000000000000000 D OverflowException 1 Постфикс m означает тип decimal 27/32
  120. 120. Упражнение №15 Задача. Что выведет следующий код?1 Write("{0:N30}", 24m * 22m / 24m); AA 22.000000000000000000000000000000 B 22.000000000000000000000000001000 C 24.000000000000000000000000000000 D OverflowException 24 · 22 24 = 24 · 22 24 = 22 1 Постфикс m означает тип decimal 27/32
  121. 121. Упражнение №16 Задача. Что выведет следующий код? Write({0:N30}, 24m * (22m / 24m)); 28/32
  122. 122. Упражнение №16 Задача. Что выведет следующий код? Write({0:N30}, 24m * (22m / 24m)); A 22.000000000000000000000000000000 28/32
  123. 123. Упражнение №16 Задача. Что выведет следующий код? Write({0:N30}, 24m * (22m / 24m)); A 22.000000000000000000000000000000 B 22.000000000000000000000000001000 28/32
  124. 124. Упражнение №16 Задача. Что выведет следующий код? Write({0:N30}, 24m * (22m / 24m)); A 22.000000000000000000000000000000 B 22.000000000000000000000000001000 C 24.000000000000000000000000000000 28/32
  125. 125. Упражнение №16 Задача. Что выведет следующий код? Write({0:N30}, 24m * (22m / 24m)); A 22.000000000000000000000000000000 B 22.000000000000000000000000001000 C 24.000000000000000000000000000000 D OverflowException 28/32
  126. 126. Упражнение №16 Задача. Что выведет следующий код? Write({0:N30}, 24m * (22m / 24m)); A 22.000000000000000000000000000000 BB 22.000000000000000000000000001000 C 24.000000000000000000000000000000 D OverflowException 28/32
  127. 127. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); 29/32
  128. 128. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); A true true 29/32
  129. 129. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); A true true B false false 29/32
  130. 130. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); A true true B false false C true false 29/32
  131. 131. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); A true true B false false C true false D false true 29/32
  132. 132. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); A true true B false false CC true false D false true 29/32
  133. 133. Упражнение №17 Задача. Что выведет следующий код? var x = 1.0m; var y = 1.00m; Write(x == y); Write(x.ToString() == y.ToString()); A true true B false false CC true false D false true Объяснение. Write(x.ToString()); // 1.0 Write(y.ToString()); // 1.00 29/32
  134. 134. Упражнение №18* Задача. Вычислить значение интеграла1 : 1 −1 1 x 1 + x 1 − x ln 2 x2 + 2 x + 1 2 x2 − 2 x + 1 dx. A 2π · arccot √ φ B 4π · arccot √ φ C eiπ − 1 D 42 1 Cм. http://math.stackexchange.com/q/562694/ 30/32
  135. 135. Методическая литература 31/32
  136. 136. Вопросы? Андрей Акиньшин, JetBrains http://aakinshin.net https://github.com/AndreyAkinshin https://twitter.com/andrey_akinshin andrey.akinshin@gmail.com 32/32

×