【问题标题】:Draw string with normalized scientific notation (superscripted )用标准化的科学记数法绘制字符串(上标)
【发布时间】:2012-03-15 13:57:27
【问题描述】:

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

比较一下,宇宙中有 10^75 个粒子。

其中 1075 以标准化的科学记数法格式化(就像我们在学校所做的那样)。

我使用 SpriteBatch.DrawString 方法,但我想不出一个有限的解决方案。有一些琐碎的:

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

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

这个任务我必须有特殊的字体吗?

【问题讨论】:

    标签: c# string silverlight xna utf


    【解决方案1】:

    我在某些地方调整了@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();
        }
    

    另外,请注意,由于字体替换,此方法可能会给您ugly results for combinations of 1,2 and 3 with other digits in an exponent。 0 和 4-9 是在 unicode 中添加的,并且在许多字体中都缺少。您应该确保使用支持所有数字的字体,例如 Arial Unicode MS、Cambria、Calibri、Consolas 或 Lucida Sans Unicode。

    【讨论】:

      【解决方案2】:

      我不熟悉 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⁵

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多