Successfully reported this slideshow.

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

1

Share

1 of 136
1 of 136

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

1

Share

Download to read offline

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

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

More Related Content

Viewers also liked

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

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

  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

×