Skip to content

Instantly share code, notes, and snippets.

@jfrijters
Created November 12, 2019 07:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfrijters/b816f8100c0aa1cce8a2ddbc0c64fbac to your computer and use it in GitHub Desktop.
Save jfrijters/b816f8100c0aa1cce8a2ddbc0c64fbac to your computer and use it in GitHub Desktop.
public readonly struct NullableDouble
{
private readonly long value;
private NullableDouble(double value)
{
var bits = BitConverter.DoubleToInt64Bits(value);
if (bits == -1)
{
// the double passed in was NaN, but the pattern equals the pattern we use for NULL values,
// so we replace it with the canonical NaN value
bits = unchecked((long)0xFFF8000000000000);
}
this.value = ~bits;
}
private double InternalToDouble() => BitConverter.Int64BitsToDouble(~value);
public bool HasValue => value != 0;
public double Value
{
get
{
if (!HasValue)
{
ThrowInvalidOperationException();
}
return InternalToDouble();
}
}
public double GetValueOrDefault()
{
if (HasValue)
{
return InternalToDouble();
}
return 0;
}
public double GetValueOrDefault(double defaultValue)
{
if (HasValue)
{
return InternalToDouble();
}
return defaultValue;
}
private static void ThrowInvalidOperationException() => throw new InvalidOperationException();
public static implicit operator NullableDouble(double value)
{
return new NullableDouble(value);
}
public static implicit operator NullableDouble(double? value)
{
if (value.HasValue)
{
return value.GetValueOrDefault();
}
return default;
}
public static implicit operator double?(NullableDouble value)
{
if (value.HasValue)
{
return value.InternalToDouble();
}
return null;
}
public static explicit operator double(NullableDouble value)
{
return value.Value;
}
public override bool Equals(object obj)
{
if (HasValue)
{
return InternalToDouble().Equals(obj);
}
return obj == null;
}
public override int GetHashCode()
{
if (HasValue)
{
return InternalToDouble().GetHashCode();
}
return 0;
}
public override string ToString()
{
double? value = this;
return value.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment