/// <summary> /// 将 <c>32</c> 位有符号整数的值转换为其指定基的等效字符串表示形式。 /// </summary> /// <param name="value">要转换的 <c>32</c> 位有符号整数。</param> /// <param name="toBase">返回值的基数,必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <returns>以 <paramref name="toBase"/> 为基的 <paramref name="value"/> /// 的字符串表示形式。</returns> /// <exception cref="ArgumentException"><paramref name="toBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> public static string ToString(this int value, int toBase) { if (toBase < 2 || toBase > 36) { throw CommonExceptions.InvalidBase(nameof(toBase), toBase); } Contract.EndContractBlock(); var neg = false; ulong ulValue; if (value < 0 && toBase == 10) { // 仅 10 进制支持负数。 neg = true; ulValue = (ulong)-value; } else { // 这里必须保证位数相同。 ulValue = (uint)value; } var buffer = new char[32]; var idx = ConvertBase(buffer, ulValue, toBase); if (neg) { buffer[--idx] = '-'; } return(new string(buffer, idx, buffer.Length - idx)); }
/// <summary> /// 将 <c>64</c> 位有符号整数的值转换为其指定基的等效字符串表示形式。 /// </summary> /// <param name="value">要转换的 <c>64</c> 位有符号整数。</param> /// <param name="toBase">返回值的基数,必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <returns>以 <paramref name="toBase"/> 为基的 <paramref name="value"/> /// 的字符串表示形式。</returns> /// <exception cref="ArgumentException"><paramref name="toBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> public static string ToString(this long value, int toBase) { if (toBase < 2 || toBase > 36) { throw CommonExceptions.InvalidBase("toBase", toBase); } Contract.EndContractBlock(); bool neg = false; ulong ulValue; if (value < 0 && toBase == 10) { // 仅 10 进制支持负数。 neg = true; ulValue = (ulong)-value; } else { ulValue = (ulong)value; } char[] buffer = new char[64]; int idx = ConvertBase(buffer, ulValue, toBase); if (neg) { buffer[--idx] = '-'; } return(new string(buffer, idx, buffer.Length - idx)); }
public static string ToString(this ulong value, int toBase) { if (toBase < 2 || toBase > 36) { throw CommonExceptions.InvalidBase("toBase", toBase); } Contract.EndContractBlock(); char[] buffer = new char[64]; int idx = ConvertBase(buffer, value, toBase); return(new string(buffer, idx, buffer.Length - idx)); }
public static string ToString(this uint value, int toBase) { if (toBase < 2 || toBase > 36) { throw CommonExceptions.InvalidBase(nameof(toBase), toBase); } Contract.EndContractBlock(); var buffer = new char[32]; var idx = ConvertBase(buffer, value, toBase); return(new string(buffer, idx, buffer.Length - idx)); }
public static ulong ToUInt64(string value, int fromBase) { if (fromBase < 2 || fromBase > 36) { throw CommonExceptions.InvalidBase("fromBase", fromBase); } Contract.EndContractBlock(); // 使用内置方法,会快一些。 if (fromBase == 2 || fromBase == 8 || fromBase == 10 || fromBase == 16) { return(System.Convert.ToUInt64(value, fromBase)); } return(StringToUInt64(value, fromBase)); }
/// <summary> /// 将指定基的数字的字符串表示形式转换为等效的 <c>32</c> 位有符号整数。 /// </summary> /// <param name="value">包含要转换的数字的字符串,使用不区分大小写的字母表示大于 <c>10</c> 的数。</param> /// <param name="fromBase"><paramref name="value"/> 中数字的基数,它必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <returns>与 <paramref name="value"/> 中数字等效的 <c>32</c> 位有符号整数, /// 如果 <paramref name="value"/> 为 <c>null</c>,则为 <c>0</c>(零)。</returns> /// <exception cref="ArgumentException"><paramref name="fromBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> /// <exception cref="ArgumentException"><paramref name="value"/> 表示一个非 <c>10</c> 为基的有符号数, /// 但前面带一个负号。</exception> /// <exception cref="FormatException"><paramref name="value"/> 包含的一个字符不是 <paramref name="fromBase"/> /// 指定的基中的有效数字。如果 <paramref name="value"/> 中的第一个字符无效,异常消息则指示没有可转换的数字; /// 否则,该消息将指示 <paramref name="value"/> 包含无效的尾随字符。</exception> /// <exception cref="OverflowException"><paramref name="value"/> 表示小于 <see cref="Int32.MinValue"/> 或大于 /// <see cref="Int32.MaxValue"/> 的数字。</exception> public static int ToInt32(string value, int fromBase) { if (fromBase < 2 || fromBase > 36) { throw CommonExceptions.InvalidBase(nameof(fromBase), fromBase); } Contract.EndContractBlock(); // 使用内置方法,会快一些。 if (fromBase == 2 || fromBase == 8 || fromBase == 10 || fromBase == 16) { return(System.Convert.ToInt32(value, fromBase)); } return(unchecked ((int)StringToUInt32(value, fromBase))); }
/// <summary> /// 对给定的基数和字符串进行检查。 /// </summary> /// <param name="value">包含要转换的数字的字符串, /// 使用不区分大小写的字母表示大于 <c>10</c> 的数。</param> /// <param name="fromBase"><paramref name="value"/> 中数字的基数, /// 它必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="fromBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> /// <exception cref="System.FormatException"> /// <paramref name="value"/> 表示一个非 <c>10</c> 为基的有符号数, /// 但前面带一个负号。</exception> private static void CheckBaseConvert(string value, int fromBase) { // 基数检查。 if (fromBase < 3 || fromBase > 36) { throw CommonExceptions.InvalidBase("fromBase", fromBase); } if (value.Length == 0) { throw CommonExceptions.NoParsibleDigits(); } // 负号检查。 if (value[0] == '-') { throw CommonExceptions.BaseConvertNegativeValue(); } }
/// <summary> /// 将 <c>64</c> 位无符号整数的值转换为其指定基的等效字符串表示形式。 /// </summary> /// <param name="buffer">字符串的缓冲区。</param> /// <param name="value">要转换的 <c>64</c> 位无符号整数。</param> /// <param name="toBase">返回值的基数,必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <returns>转换后字符串的起始索引。</returns> /// <exception cref="System.ArgumentException"> /// <paramref name="toBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> private static int ConvertBase(char[] buffer, ulong value, int toBase) { if (toBase < 2 || toBase > 36) { throw CommonExceptions.InvalidBase("toBase", toBase); } // 从后向前转换,不必反转字符串。 ulong ulBase = (ulong)toBase; int idx = buffer.Length - 1; do { ulong quot = value / ulBase; buffer[idx--] = CharExt.BaseDigits[value - quot * ulBase]; value = quot; } while (value > 0); return idx + 1; }
/// <summary> /// 将指定基的数字的字符串表示形式转换为等效的 <c>8</c> 位无符号整数。 /// </summary> /// <param name="value">包含要转换的数字的字符串,使用不区分大小写的字母表示大于 <c>10</c> 的数。</param> /// <param name="fromBase"><paramref name="value"/> 中数字的基数,它必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <returns>与 <paramref name="value"/> 中数字等效的 <c>8</c> 位无符号整数, /// 如果 <paramref name="value"/> 为 <c>null</c>,则为 <c>0</c>(零)。</returns> /// <exception cref="ArgumentException"><paramref name="fromBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> /// <exception cref="ArgumentException"><paramref name="value"/> 表示一个非 <c>10</c> 为基的有符号数, /// 但前面带一个负号。</exception> /// <exception cref="FormatException"><paramref name="value"/> 包含的一个字符不是 <paramref name="fromBase"/> /// 指定的基中的有效数字。如果 <paramref name="value"/> 中的第一个字符无效,异常消息则指示没有可转换的数字; /// 否则,该消息将指示 <paramref name="value"/> 包含无效的尾随字符。</exception> /// <exception cref="OverflowException"><paramref name="value"/> 表示小于 <see cref="Byte.MinValue"/> 或大于 /// <see cref="Byte.MaxValue"/> 的数字。</exception> public static byte ToByte(string value, int fromBase) { if (fromBase < 2 || fromBase > 36) { throw CommonExceptions.InvalidBase("fromBase", fromBase); } Contract.EndContractBlock(); // 使用内置方法,会快一些。 if (fromBase == 2 || fromBase == 8 || fromBase == 10 || fromBase == 16) { return(System.Convert.ToByte(value, fromBase)); } uint uValue = StringToUInt32(value, fromBase); if (uValue > byte.MaxValue) { throw CommonExceptions.OverflowByte(); } return((byte)uValue); }
public static ushort ToUInt16(string value, int fromBase) { if (fromBase < 2 || fromBase > 36) { throw CommonExceptions.InvalidBase(nameof(fromBase), fromBase); } Contract.EndContractBlock(); // 使用内置方法,会快一些。 if (fromBase == 2 || fromBase == 8 || fromBase == 10 || fromBase == 16) { return(System.Convert.ToUInt16(value, fromBase)); } var uValue = StringToUInt32(value, fromBase); if (uValue > ushort.MaxValue) { throw CommonExceptions.OverflowUInt16(); } return((ushort)uValue); }
/// <summary> /// 将指定基的数字的字符串表示形式转换为等效的 <c>16</c> 位有符号整数。 /// </summary> /// <param name="value">包含要转换的数字的字符串,使用不区分大小写的字母表示大于 <c>10</c> 的数。</param> /// <param name="fromBase"><paramref name="value"/> 中数字的基数,它必须位于 <c>2</c> 到 <c>36</c> 之间。</param> /// <returns>与 <paramref name="value"/> 中数字等效的 <c>16</c> 位有符号整数, /// 如果 <paramref name="value"/> 为 <c>null</c>,则为 <c>0</c>(零)。</returns> /// <exception cref="ArgumentException"><paramref name="fromBase"/> 不是 <c>2</c> 到 <c>36</c> 之间的数字。</exception> /// <exception cref="ArgumentException"><paramref name="value"/> 表示一个非 <c>10</c> 为基的有符号数, /// 但前面带一个负号。</exception> /// <exception cref="FormatException"><paramref name="value"/> 包含的一个字符不是 <paramref name="fromBase"/> /// 指定的基中的有效数字。如果 <paramref name="value"/> 中的第一个字符无效,异常消息则指示没有可转换的数字; /// 否则,该消息将指示 <paramref name="value"/> 包含无效的尾随字符。</exception> /// <exception cref="OverflowException"><paramref name="value"/> 表示小于 <see cref="Int16.MinValue"/> 或大于 /// <see cref="Int16.MaxValue"/> 的数字。</exception> public static short ToInt16(string value, int fromBase) { if (fromBase < 2 || fromBase > 36) { throw CommonExceptions.InvalidBase("fromBase", fromBase); } Contract.EndContractBlock(); // 使用内置方法,会快一些。 if (fromBase == 2 || fromBase == 8 || fromBase == 10 || fromBase == 16) { return(System.Convert.ToInt16(value, fromBase)); } uint uValue = StringToUInt32(value, fromBase); // fromBase 总是不为 10。 if (uValue <= ushort.MaxValue) { return(unchecked ((short)uValue)); } throw CommonExceptions.OverflowInt16(); }
public static sbyte ToSByte(string value, int fromBase) { if (fromBase < 2 || fromBase > 36) { throw CommonExceptions.InvalidBase(nameof(fromBase), fromBase); } Contract.EndContractBlock(); // 使用内置方法,会快一些。 if (fromBase == 2 || fromBase == 8 || fromBase == 10 || fromBase == 16) { return(System.Convert.ToSByte(value, fromBase)); } var uValue = StringToUInt32(value, fromBase); // fromBase 总是不为 10。 if (uValue <= byte.MaxValue) { return(unchecked ((sbyte)uValue)); } throw CommonExceptions.OverflowSByte(); }