1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 /*============================================================ 7 ** 8 ** Class: Int64.cs 9 ** 10 ** 11 ** Purpose: This class will encapsulate a long and provide an 12 ** Object representation of it. 13 ** 14 ** 15 ===========================================================*/ 16 namespace System { 17 18 using System; 19 using System.Globalization; 20 ///#if GENERICS_WORK 21 /// using System.Numerics; 22 ///#endif 23 using System.Runtime.InteropServices; 24 using System.Diagnostics.Contracts; 25 26 [Serializable] 27 [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] 28 [System.Runtime.InteropServices.ComVisible(true)] 29 #if GENERICS_WORK 30 public struct Int64 : IComparable, IFormattable, IConvertible 31 , IComparable<Int64>, IEquatable<Int64> 32 /// , IArithmetic<Int64> 33 #else 34 public struct Int64 : IComparable, IFormattable, IConvertible 35 #endif 36 { 37 internal long m_value; 38 39 public const long MaxValue = 0x7fffffffffffffffL; 40 public const long MinValue = unchecked((long)0x8000000000000000L); 41 42 // Compares this object to another object, returning an integer that 43 // indicates the relationship. 44 // Returns a value less than zero if this object 45 // null is considered to be less than any instance. 46 // If object is not of type Int64, this method throws an ArgumentException. 47 // CompareToSystem.Int6448 public int CompareTo(Object value) { 49 if (value == null) { 50 return 1; 51 } 52 if (value is Int64) { 53 // Need to use compare because subtraction will wrap 54 // to positive for very large neg numbers, etc. 55 long i = (long)value; 56 if (m_value < i) return -1; 57 if (m_value > i) return 1; 58 return 0; 59 } 60 throw new ArgumentException (Environment.GetResourceString("Arg_MustBeInt64")); 61 } 62 CompareToSystem.Int6463 public int CompareTo(Int64 value) { 64 // Need to use compare because subtraction will wrap 65 // to positive for very large neg numbers, etc. 66 if (m_value < value) return -1; 67 if (m_value > value) return 1; 68 return 0; 69 } 70 EqualsSystem.Int6471 public override bool Equals(Object obj) { 72 if (!(obj is Int64)) { 73 return false; 74 } 75 return m_value == ((Int64)obj).m_value; 76 } 77 78 [System.Runtime.Versioning.NonVersionable] EqualsSystem.Int6479 public bool Equals(Int64 obj) 80 { 81 return m_value == obj; 82 } 83 84 // The value of the lower 32 bits XORed with the uppper 32 bits. GetHashCodeSystem.Int6485 public override int GetHashCode() { 86 return (unchecked((int)((long)m_value)) ^ (int)(m_value >> 32)); 87 } 88 89 [System.Security.SecuritySafeCritical] // auto-generated ToStringSystem.Int6490 public override String ToString() { 91 Contract.Ensures(Contract.Result<String>() != null); 92 return Number.FormatInt64(m_value, null, NumberFormatInfo.CurrentInfo); 93 } 94 95 [System.Security.SecuritySafeCritical] // auto-generated ToStringSystem.Int6496 public String ToString(IFormatProvider provider) { 97 Contract.Ensures(Contract.Result<String>() != null); 98 return Number.FormatInt64(m_value, null, NumberFormatInfo.GetInstance(provider)); 99 } 100 101 [System.Security.SecuritySafeCritical] // auto-generated ToStringSystem.Int64102 public String ToString(String format) { 103 Contract.Ensures(Contract.Result<String>() != null); 104 return Number.FormatInt64(m_value, format, NumberFormatInfo.CurrentInfo); 105 } 106 107 [System.Security.SecuritySafeCritical] // auto-generated ToStringSystem.Int64108 public String ToString(String format, IFormatProvider provider) { 109 Contract.Ensures(Contract.Result<String>() != null); 110 return Number.FormatInt64(m_value, format, NumberFormatInfo.GetInstance(provider)); 111 } 112 ParseSystem.Int64113 public static long Parse(String s) { 114 return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo); 115 } 116 ParseSystem.Int64117 public static long Parse(String s, NumberStyles style) { 118 NumberFormatInfo.ValidateParseStyleInteger(style); 119 return Number.ParseInt64(s, style, NumberFormatInfo.CurrentInfo); 120 } 121 ParseSystem.Int64122 public static long Parse(String s, IFormatProvider provider) { 123 return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider)); 124 } 125 126 127 // Parses a long from a String in the given style. If 128 // a NumberFormatInfo isn't specified, the current culture's 129 // NumberFormatInfo is assumed. 130 // ParseSystem.Int64131 public static long Parse(String s, NumberStyles style, IFormatProvider provider) { 132 NumberFormatInfo.ValidateParseStyleInteger(style); 133 return Number.ParseInt64(s, style, NumberFormatInfo.GetInstance(provider)); 134 } 135 TryParseSystem.Int64136 public static Boolean TryParse(String s, out Int64 result) { 137 return Number.TryParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result); 138 } 139 TryParseSystem.Int64140 public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Int64 result) { 141 NumberFormatInfo.ValidateParseStyleInteger(style); 142 return Number.TryParseInt64(s, style, NumberFormatInfo.GetInstance(provider), out result); 143 } 144 145 // 146 // IConvertible implementation 147 // 148 GetTypeCodeSystem.Int64149 public TypeCode GetTypeCode() { 150 return TypeCode.Int64; 151 } 152 153 /// <internalonly/> IConvertible.ToBooleanSystem.Int64154 bool IConvertible.ToBoolean(IFormatProvider provider) { 155 return Convert.ToBoolean(m_value); 156 } 157 158 /// <internalonly/> IConvertible.ToCharSystem.Int64159 char IConvertible.ToChar(IFormatProvider provider) { 160 return Convert.ToChar(m_value); 161 } 162 163 /// <internalonly/> IConvertible.ToSByteSystem.Int64164 sbyte IConvertible.ToSByte(IFormatProvider provider) { 165 return Convert.ToSByte(m_value); 166 } 167 168 /// <internalonly/> IConvertible.ToByteSystem.Int64169 byte IConvertible.ToByte(IFormatProvider provider) { 170 return Convert.ToByte(m_value); 171 } 172 173 /// <internalonly/> IConvertible.ToInt16System.Int64174 short IConvertible.ToInt16(IFormatProvider provider) { 175 return Convert.ToInt16(m_value); 176 } 177 178 /// <internalonly/> IConvertible.ToUInt16System.Int64179 ushort IConvertible.ToUInt16(IFormatProvider provider) { 180 return Convert.ToUInt16(m_value); 181 } 182 183 /// <internalonly/> IConvertible.ToInt32System.Int64184 int IConvertible.ToInt32(IFormatProvider provider) { 185 return Convert.ToInt32(m_value); 186 } 187 188 /// <internalonly/> IConvertible.ToUInt32System.Int64189 uint IConvertible.ToUInt32(IFormatProvider provider) { 190 return Convert.ToUInt32(m_value); 191 } 192 193 /// <internalonly/> IConvertible.ToInt64System.Int64194 long IConvertible.ToInt64(IFormatProvider provider) { 195 return m_value; 196 } 197 198 /// <internalonly/> IConvertible.ToUInt64System.Int64199 ulong IConvertible.ToUInt64(IFormatProvider provider) { 200 return Convert.ToUInt64(m_value); 201 } 202 203 /// <internalonly/> IConvertible.ToSingleSystem.Int64204 float IConvertible.ToSingle(IFormatProvider provider) { 205 return Convert.ToSingle(m_value); 206 } 207 208 /// <internalonly/> IConvertible.ToDoubleSystem.Int64209 double IConvertible.ToDouble(IFormatProvider provider) { 210 return Convert.ToDouble(m_value); 211 } 212 213 /// <internalonly/> IConvertible.ToDecimalSystem.Int64214 Decimal IConvertible.ToDecimal(IFormatProvider provider) { 215 return Convert.ToDecimal(m_value); 216 } 217 218 /// <internalonly/> IConvertible.ToDateTimeSystem.Int64219 DateTime IConvertible.ToDateTime(IFormatProvider provider) { 220 throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Int64", "DateTime")); 221 } 222 223 /// <internalonly/> IConvertible.ToTypeSystem.Int64224 Object IConvertible.ToType(Type type, IFormatProvider provider) { 225 return Convert.DefaultToType((IConvertible)this, type, provider); 226 } 227 228 ///#if GENERICS_WORK 229 /// // 230 /// // IArithmetic<Int64> implementation 231 /// // 232 /// 233 /// /// <internalonly/> 234 /// Int64 IArithmetic<Int64>.AbsoluteValue(out bool overflowed) { 235 /// overflowed = (m_value == MinValue); // -m_value overflows 236 /// return (m_value < 0 ? -m_value : m_value); 237 /// } 238 /// 239 /// /// <internalonly/> 240 /// Int64 IArithmetic<Int64>.Negate(out bool overflowed) { 241 /// overflowed = (m_value == MinValue); // Negate(MinValue) overflows 242 /// return (-m_value); 243 /// } 244 /// 245 /// /// <internalonly/> 246 /// Int64 IArithmetic<Int64>.Sign(out bool overflowed) { 247 /// overflowed = false; 248 /// return (m_value >= 0 ? (m_value == 0 ? 0 : 1) : -1); 249 /// } 250 /// 251 /// /// <internalonly/> 252 /// Int64 IArithmetic<Int64>.Add(Int64 addend, out bool overflowed) { 253 /// // 254 /// // true arithmetic range check => re-written for signed int 255 /// // ------------------------------- ------------------------------- 256 /// // ( ((m_value + addend) > MaxValue) => ( (addend > 0 && m_value > MaxValue - addend) 257 /// // ||((m_value + addend) < MinValue)) ||(addend < 0 && m_value < MinValue - addend) ) 258 /// 259 /// 260 /// overflowed = ((addend > 0) && (m_value > (MaxValue - addend))) || 261 /// ((addend < 0) && (m_value < (MinValue - addend))); 262 /// return unchecked(m_value + addend); 263 /// } 264 /// 265 /// /// <internalonly/> 266 /// Int64 IArithmetic<Int64>.Subtract(Int64 subtrahend, out bool overflowed) { 267 /// // 268 /// // true arithmetic range check => re-written for signed int 269 /// // ------------------------------- ------------------------------- 270 /// // ( ((m_value - subtrahend) > MaxValue) => ( (subtrahend < 0 && m_value > MaxValue + subtrahend) 271 /// // ||((m_value - subtrahend) < MinValue)) ||(subtrahend > 0 && m_value < MinValue + subtrahend) ) 272 /// 273 /// overflowed = ((subtrahend < 0) && (m_value > (MaxValue + subtrahend))) || 274 /// ((subtrahend > 0) && (m_value < (MinValue + subtrahend))); 275 /// return unchecked(m_value - subtrahend); 276 /// } 277 /// 278 /// /// <internalonly/> 279 /// Int64 IArithmetic<Int64>.Multiply(Int64 multiplier, out bool overflowed) { 280 /// overflowed = Int64MultiplyOverflowed(m_value, multiplier); 281 /// return unchecked(m_value * multiplier); 282 /// } 283 /// 284 /// // 285 /// // Please refer to VM\jithelpers.cpp JIT_LMulOvf for more detailed information 286 /// // 287 /// // We perform this overflow check here instead of simply using a 'checked' operation 288 /// // as it is roughly 1,345X faster. 289 /// // 290 /// static Boolean Int64MultiplyOverflowed(Int64 val1, Int64 val2) { 291 /// Int64 ret; 292 /// 293 /// // Remember the sign of the result 294 /// Int32 sign = (Int32) (Hi32Bits(val1) ^ Hi32Bits(val2)); 295 /// 296 /// // Convert to unsigned multiplication 297 /// if (val1 < 0) val1 = -val1; 298 /// if (val2 < 0) val2 = -val2; 299 /// 300 /// // Get the upper 32 bits of the numbers 301 /// UInt32 val1High = Hi32Bits(val1); 302 /// UInt32 val2High = Hi32Bits(val2); 303 /// 304 /// UInt64 valMid; 305 /// 306 /// if (val1High == 0) { 307 /// // Compute the 'middle' bits of the long multiplication 308 /// valMid = Mul32x32To64(val2High, (UInt32)val1); 309 /// } 310 /// else { 311 /// if (val2High != 0) 312 /// return true; 313 /// // Compute the 'middle' bits of the long multiplication 314 /// valMid = Mul32x32To64(val1High, (UInt32)val2); 315 /// } 316 /// 317 /// // See if any bits after bit 32 are set 318 /// if (Hi32Bits((Int64)valMid) != 0) 319 /// return true; 320 /// 321 /// ret = (Int64) (Mul32x32To64((UInt32)val1, (UInt32)val2) + (valMid << 32)); 322 /// 323 /// // check for overflow 324 /// if (Hi32Bits(ret) < (UInt32)valMid) 325 /// return true; 326 /// 327 /// if (sign >= 0) { 328 /// // have we spilled into the sign bit? 329 /// if (ret < 0) 330 /// return true; 331 /// } 332 /// else { 333 /// ret = -ret; 334 /// // have we spilled into the sign bit? 335 /// if (ret > 0) 336 /// return true; 337 /// } 338 /// return false; 339 /// } 340 /// 341 /// // 342 /// // helper method to get high 32-bit of 64-bit int 343 /// // 344 /// static UInt32 Hi32Bits(Int64 x) { 345 /// return ((UInt32)((UInt64)(x) >> 32)); 346 /// } 347 /// 348 /// // 349 /// // helper method to multiply two 32-bit uints 350 /// // 351 /// static UInt64 Mul32x32To64(UInt32 x, UInt32 y) { 352 /// return ((UInt64)(x) * (UInt64)(y)); 353 /// } 354 /// 355 /// /// <internalonly/> 356 /// Int64 IArithmetic<Int64>.Divide(Int64 divisor, out bool overflowed) { 357 /// // signed integer division can overflow. Consider the following 358 /// // 8-bit case: -128/-1 = 128. 359 /// // 128 won't fit into a signed 8-bit integer, instead you will end up 360 /// // with -128. 361 /// // 362 /// // Because of this corner case, we must check if the numerator 363 /// // is MinValue and if the denominator is -1. 364 /// 365 /// overflowed = (divisor == -1 && m_value == MinValue); 366 /// 367 /// if (overflowed) { 368 /// // we special case (MinValue / (-1)) for Int32 and Int64 as 369 /// // unchecked still throws OverflowException when variables 370 /// // are used instead of constants 371 /// return MinValue; 372 /// } 373 /// else { 374 /// return unchecked(m_value / divisor); 375 /// } 376 /// } 377 /// 378 /// /// <internalonly/> 379 /// Int64 IArithmetic<Int64>.DivideRemainder(Int64 divisor, out Int64 remainder, out bool overflowed) { 380 /// overflowed = (divisor == -1 && m_value == MinValue); 381 /// 382 /// if (overflowed) { 383 /// // we special case (MinValue / (-1)) for Int32 and Int64 as 384 /// // unchecked still throws OverflowException when variables 385 /// // are used instead of constants 386 /// remainder = 0; 387 /// return MinValue; 388 /// } 389 /// else { 390 /// remainder = (m_value % divisor); 391 /// return unchecked(m_value / divisor); 392 /// } 393 /// } 394 /// 395 /// /// <internalonly/> 396 /// Int64 IArithmetic<Int64>.Remainder(Int64 divisor, out bool overflowed) { 397 /// overflowed = false; 398 /// 399 /// if (divisor == -1 && m_value == MinValue) { 400 /// // we special case (MinValue % (-1)) for Int32 and Int64 as 401 /// // unchecked still throws OverflowException when variables 402 /// // are used instead of constants 403 /// return 0; 404 /// } 405 /// else { 406 /// return (m_value % divisor); 407 /// } 408 /// } 409 /// 410 /// /// <internalonly/> 411 /// ArithmeticDescriptor<Int64> IArithmetic<Int64>.GetDescriptor() { 412 /// if (s_descriptor == null) { 413 /// s_descriptor = new Int64ArithmeticDescriptor( ArithmeticCapabilities.One 414 /// | ArithmeticCapabilities.Zero 415 /// | ArithmeticCapabilities.MaxValue 416 /// | ArithmeticCapabilities.MinValue); 417 /// } 418 /// return s_descriptor; 419 /// } 420 /// 421 /// private static Int64ArithmeticDescriptor s_descriptor; 422 /// 423 /// class Int64ArithmeticDescriptor : ArithmeticDescriptor<Int64> { 424 /// public Int64ArithmeticDescriptor(ArithmeticCapabilities capabilities) : base(capabilities) {} 425 /// 426 /// public override Int64 One { 427 /// get { 428 /// return (Int64) 1; 429 /// } 430 /// } 431 /// 432 /// public override Int64 Zero { 433 /// get { 434 /// return (Int64) 0; 435 /// } 436 /// } 437 /// 438 /// public override Int64 MinValue { 439 /// get { 440 /// return Int64.MinValue; 441 /// } 442 /// } 443 /// 444 /// public override Int64 MaxValue { 445 /// get { 446 /// return Int64.MaxValue; 447 /// } 448 /// } 449 /// } 450 ///#endif // #if GENERICS_WORK 451 452 } 453 } 454