使用标准化科学记数法绘制字符串(上标)

我想在我的游戏中绘制以下字符串

为了比较,宇宙中有10 ^ 75个粒子。

其中10 75采用标准化的科学记数法格式化(正如我们在学校所做的那样)。

我使用SpriteBatch.DrawString方法,但我无法找出一个解决方案。 有一些微不足道的:

  • 绘制两个字符串,其中第二个字符串的字体较小或缩放。
  • 画一个图像。

我一直在看UTF表,但似乎不可能。

我必须为此任务使用特殊字体吗?

我不熟悉XNA,但在Silverlight项目中,我必须做同样的事情,我最终用上标字符构建科学记数字。

您不需要特殊字体,只需要具有下面使用的上标字符的Unicode字体。

下面是将数字0-9映射到相应字符的代码:

private static string GetSuperscript(int digit) { switch (digit) { case 0: return "\x2070"; case 1: return "\x00B9"; case 2: return "\x00B2"; case 3: return "\x00B3"; case 4: return "\x2074"; case 5: return "\x2075"; case 6: return "\x2076"; case 7: return "\x2077"; case 8: return "\x2078"; case 9: return "\x2079"; default: return string.Empty; } } 

这会将您原来的双重转换为科学记数法

  public static string FormatAsPowerOfTen(double? value, int decimals) { if(!value.HasValue) { return string.Empty; } var exp = (int)Math.Log10(value.Value); var fmt = string.Format("{{0:F{0}}}x10{{1}}", decimals); return string.Format(fmt, value / Math.Pow(10, exp), FormatExponentWithSuperscript(exp)); } private static string FormatExponentWithSuperscript(int exp) { var sb = new StringBuilder(); bool isNegative = false; if(exp < 0) { isNegative = true; exp = -exp; } while (exp != 0) { sb.Insert(0, GetSuperscript(exp%10)); exp = exp/10; } if(isNegative) { sb.Insert(0, "-"); } return sb.ToString(); } 

所以现在你应该能够使用FormatAsPowerOfTen(123400, 2)产生1.23x10⁵

我在某些地方调整了@Phil的答案,并希望与您分享我的版本。

  public static string FormatAsPowerOfTen(this double? value, int decimals) { if (!value.HasValue) return string.Empty; else return FormatAsPowerOfTen(value.Value, decimals); } public static string FormatAsPowerOfTen(this double value, int decimals) { const string Mantissa = "{{0:F{0}}}"; // Use Floor to round negative numbers so, that the number will have one digit before the decimal separator, rather than none. var exp = Convert.ToInt32(Math.Floor(Math.Log10(value))); string fmt = string.Format(Mantissa, decimals); // Do not show 10^0, as this is not commonly used in scientific publications. if (exp != 0) fmt = string.Concat(fmt, " × 10{1}"); // Use unicode multiplication sign, rather than x. return string.Format(fmt, value / Math.Pow(10, exp), FormatExponentWithSuperscript(exp)); } private static string FormatExponentWithSuperscript(int exp) { bool isNegative = false; var sb = new StringBuilder(); if (exp < 0) { isNegative = true; exp = -exp; } while (exp != 0) { sb.Insert(0, GetSuperscript(exp % 10)); exp = exp / 10; } if (isNegative) sb.Insert(0, '⁻'); //Use unicode SUPERSCRIPT minus return sb.ToString(); } 

另请注意,由于字体替换, 对于1,2和3与指数中其他数字的组合 ,此方法可能会给您带来难看的结果 。 0和4-9以unicode添加,并且从许多字体中丢失。 您应确保使用支持所有数字的字体,如Arial Unicode MS,Cambria,Calibri,Consolas或Lucida Sans Unicode。