2012-02-25 63 views
1

我想提請以下字符串在我的遊戲拉繩與標準化的科學記數法(上標)

比較,有10^75的粒子在宇宙中。

其中10 在一個標準化的科學記數法的格式(如我們在學校裏一直在做)。

我使用SpriteBatch.DrawString方法,但我找不出一個有限的解決方案。有一些小瑣事:

  • 繪製兩個字符串,其中第二個字符串的字體較小或縮放。
  • 繪製圖像。

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

我必須爲此任務設置特殊字體嗎?

回答

3

我對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⁵

0

我在某些位置調整了@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。