在ASP.NET中将具有小数语言中性的价格值转换为整数

在ASP.NET中将具有小数语言中性的价格值转换为整数,asp.net,vb.net,integer,decimal,number-formatting,Asp.net,Vb.net,Integer,Decimal,Number Formatting,我想转换十进制数(精确的价格值),可能: a) 包含1或2个小数 b) 将或,作为十进制分隔符 以美分表示的整数值 因此: 3,5变为350 3,50变为350 3.5变为350 3.50变为350 1000.34变为100034 1.000,34变为100034 如果不构建执行所有这些检查的函数,ASP.NET中是否有方法更快地执行这些检查 **更新** 感谢尼古拉斯: 我现在在VB.NET中有了这个 Private Shared Function ConvertToPriceInCents(

我想转换十进制数(精确的价格值),可能: a) 包含1或2个小数 b) 将
作为十进制分隔符

以美分表示的整数值

因此:

3,5变为350
3,50变为350
3.5变为350
3.50变为350
1000.34变为100034
1.000,34变为100034

如果不构建执行所有这些检查的函数,ASP.NET中是否有方法更快地执行这些检查

**更新** 感谢尼古拉斯:

我现在在VB.NET中有了这个

Private Shared Function ConvertToPriceInCents(s As String) As Integer
        If s Is Nothing Then
            Throw New ArgumentNullException("s")
        End If
        If s = "" Then
            Throw New ArgumentOutOfRangeException("s", "s must not be empty.")
        End If

        Dim priceInCents As Integer = 0
        Dim scale As Integer = 1
        Dim i As Integer = s.Length

        ' collect the fractional part; identify the decimal separator
        While System.Threading.Interlocked.Decrement(i) >= 0
            Dim n As Integer = Asc(s(i)) - Asc("0"c)

            If n < 0 OrElse n > 9 Then
                Exit While
            End If
            ' bail out, we found the decimal separator
            priceInCents += n * scale

            scale *= 10
        End While

        Dim decimalSeparator As Char = s(i)
        Dim groupSeparator As Char = If(decimalSeparator = "."c, ","c, "."c)

        If scale <> 10 AndAlso scale <> 100 Then
            Throw New FormatException("value must have 1 or 2 digits to the right of the decimal separator")
        End If
        If decimalSeparator <> ","c AndAlso decimalSeparator <> "."c Then
            Throw New FormatException("Invalid decimal separator")
        End If

        ' if we only found one digit to the right of the decimal separator,
        ' we need to normalize and scale up by a factor of 10 (so something like 3.5 represents 350 cents)
        If scale = 10 Then
            scale *= 10
            priceInCents *= 10
        End If

        ' get the integer portion of value
        ' we're being a little lax here and ignoring group separators regardless of position.
        ' It's a hard thing to do, especially when you consider that
        ' - group sizes vary across cultures, and
        ' - aren't necessarily uniform in size.
        While System.Threading.Interlocked.Decrement(i) >= 0
            Dim c As Char = s(i)
            If c = groupSeparator Then
                Continue While
            End If

            Dim n As Integer = Asc(s(i)) - Asc("0"c)
            If n < 0 OrElse n > 9 Then
                Throw New FormatException("invalid group separator")
            End If

            priceInCents += n * scale

            scale *= 10
        End While

        ' If we haven't thrown an exception yet,
        ' we have the value in cents: return it.
        Return priceInCents
    End Function
私有共享函数ConvertToPriceInCents(作为字符串)作为整数
如果s什么都不是
抛出新的ArgumentNullException(“s”)
如果结束
如果s=”“,则
抛出新ArgumentOutOfRangeException(“s”,“s不能为空”)
如果结束
Dim priceInCents为整数=0
尺寸比例为整数=1
尺寸i为整数=s.长度
'收集小数部分;标识十进制分隔符
而系统线程联锁减量(i)>=0
尺寸n为整数=Asc(s(i))-Asc(“0”c)
如果n<0或n>9,则
退出时
如果结束
“保释吧,我们找到了小数点分隔符
价格激励+=n*比例
比例*=10
结束时
尺寸小数分隔符,字符=s(i)
Dim GROUPSELDER As Char=If(小数分隔符=“.c”,“c”,“c”)
如果标度为10,也标度为100,则
抛出新FormatException(“值必须在十进制分隔符右侧有1或2位数字”)
如果结束
如果使用小数分隔符“,”c,也可以使用小数分隔符“,”c,则
抛出新FormatException(“无效的十进制分隔符”)
如果结束
'如果我们只在十进制分隔符的右边找到一个数字,
我们需要正常化,并将其放大10倍(因此3.5代表350美分)
如果比例=10,则
比例*=10
价格激励*=10
如果结束
'获取值的整数部分
我们在这里有点松懈,不管位置如何,都忽略了分组分隔符。
这是件很难的事,尤其是当你考虑到的时候
“-组大小因文化而异,并且
“-不一定大小一致。
而系统线程联锁减量(i)>=0
尺寸c为字符=s(i)
如果c=groupSeparator,则
继续
如果结束
尺寸n为整数=Asc(s(i))-Asc(“0”c)
如果n<0或n>9,则
抛出新FormatException(“无效的组分隔符”)
如果结束
价格激励+=n*比例
比例*=10
结束时
“如果我们还没有抛出异常,
“我们的价值单位是美分:返回它。
退货价格激励
端函数

您编写的方法如下所示:

static int ConvertToPriceInCents( string s )
{
  if ( s == null ) throw new ArgumentNullException("s") ;
  if ( s == ""   ) throw new ArgumentOutOfRangeException("s","s must not be empty." ) ;

  int priceInCents = 0 ;
  int scale        = 1 ;
  int i            = s.Length ;

  // collect the fractional part; identify the decimal separator
  while ( --i >= 0 )
  {
    int n = s[i] - '0' ;

    if ( n < 0 || n > 9 ) break ; // bail out, we found the decimal separator

    priceInCents += n*scale ;
    scale *= 10 ;

  }

  char decimalSeparator = s[i] ;
  char groupSeparator   = decimalSeparator == '.' ? ',' : '.' ;

  if ( scale            != 10  && scale            != 100 ) throw new FormatException("value must have 1 or 2 digits to the right of the decimal separator") ;
  if ( decimalSeparator != ',' && decimalSeparator != '.' ) throw new FormatException("Invalid decimal separator") ;

  // if we only found one digit to the right of the decimal separator,
  // we need to normalize and scale up by a factor of 10 (so something like 3.5 represents 350 cents)
  if ( scale == 10 )
  {
    scale        *= 10 ;
    priceInCents *= 10 ;
  }

  // get the integer portion of value
  // we're being a little lax here and ignoring group separators regardless of position.
  // It's a hard thing to do, especially when you consider that
  // - group sizes vary across cultures, and
  // - aren't necessarily uniform in size.
  while ( --i >= 0 )
  {
    char c = s[i] ;
    if ( c == groupSeparator ) continue ;

    int n = s[i] - '0' ;
    if ( n < 0 || n > 9 ) throw new FormatException("invalid group separator") ;

    priceInCents += n*scale ;
    scale        *= 10      ;

  }

  // If we haven't thrown an exception yet,
  // we have the value in cents: return it.
  return priceInCents ;
}
static int ConvertToPriceInCents(字符串s)
{
如果(s==null)抛出新的ArgumentNullException(“s”);
如果(s==“”)抛出新ArgumentOutOfRangeException(“s”,“s不能为空”);
int priceInCents=0;
int标度=1;
int i=s.长度;
//收集小数部分;标识小数分隔符
而(--i>=0)
{
int n=s[i]-“0”;
如果(n<0 | | n>9)中断;//退出,我们找到了十进制分隔符
价格激励+=n*标度;
比例*=10;
}
字符小数分隔符=s[i];
char-groupSeparator=decimalSeparator='.'?',':';
如果(scale!=10&&scale!=100)抛出新的FormatException(“值必须在小数点分隔符右侧有1或2位”);
如果(decimalSeparator!=','&&decimalSeparator!='。)抛出新的FormatException(“无效的十进制分隔符”);
//如果我们只在小数点分隔符的右边找到一个数字,
//我们需要正常化,并将其放大10倍(因此3.5代表350美分)
如果(比例==10)
{
比例*=10;
价格诱因*=10;
}
//获取值的整数部分
//我们在这里有点松懈,不管位置如何,都忽略了组分隔符。
这是件很难的事,尤其是当你考虑到的时候。
//-团队规模因文化而异,并且
//-不一定大小一致。
而(--i>=0)
{
char c=s[i];
如果(c==groupSeparator)继续;
int n=s[i]-“0”;
如果(n<0 | | n>9)抛出新的FormatException(“无效的组分隔符”);
价格激励+=n*标度;
比例*=10;
}
//如果我们还没有抛出异常,
//我们有以美分表示的价值:返回它。
退货价格激励;
}

我添加了您代码的VB.NET翻译,尽管它仍然包含一些错误……您知道如何修复它们吗?