Ответ
Тип double в C# — это 64-битное число с плавающей запятой, соответствующее стандарту IEEE 754. В памяти оно занимает 8 байт (64 бита) и состоит из трех частей:
- Знак (Sign) — 1 бит.
0— положительное число.1— отрицательное число.
- Экспонента (Exponent) — 11 бит.
- Хранит степень двойки для нормализованного числа. Используется смещенное представление (bias = 1023). Это означает, что фактическая экспонента вычисляется как
хранимое_значение - 1023.
- Хранит степень двойки для нормализованного числа. Используется смещенное представление (bias = 1023). Это означает, что фактическая экспонента вычисляется как
- Мантисса (Mantissa/Фракция) — 52 бита.
- Хранит дробную часть числа. Для нормализованных чисел подразумевается ведущая
1(скрытый бит), поэтому фактическая точность — 53 бита.
- Хранит дробную часть числа. Для нормализованных чисел подразумевается ведущая
Формула представления: (-1)^знак * (1 + мантисса) * 2^(экспонента - 1023)
Пример в коде:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct DoubleToLong
{
[FieldOffset(0)] public double DoubleValue;
[FieldOffset(0)] public long LongValue;
}
public class Program
{
public static void Main()
{
double num = -123.456;
var converter = new DoubleToLong { DoubleValue = num };
long bits = converter.LongValue;
// Извлекаем части
long sign = (bits >> 63) & 0x01;
long exponent = (bits >> 52) & 0x7FF;
long mantissa = bits & 0xFFFFFFFFFFFFF;
Console.WriteLine($"Число: {num}");
Console.WriteLine($"Знак: {sign}");
Console.WriteLine($"Экспонента (смещенная): {exponent}");
Console.WriteLine($"Мантисса (hex): 0x{mantissa:X}");
}
}
Практические следствия:
- Точность: ~15-17 десятичных знаков.
- Ошибки округления: Из-за двоичного представления некоторые десятичные дроби (например, 0.1) не могут быть представлены точно. Это приводит к известной проблеме
0.1 + 0.2 != 0.3. - Специальные значения:
double.NaN(Not a Number) — результат неопределенных операций (например,0.0 / 0.0).double.PositiveInfinityиdouble.NegativeInfinity— результат переполнения (например,1.0 / 0.0).
Для точных финансовых расчетов используйте decimal.