一串表示带符号和小数位的二进制字符串,"111110010010" ,其中最高位为符号位,最右边4位为小数位,除最左边符号位之外由左至右依次表示:2的6次冥 2的5次冥 2的4次冥 2的3次冥 2的2次冥 2的1次冥 2的0次冥 2的-1次冥 2的-2次冥 2的-3次冥 2的-4次冥,符号位为1表示负数。如果为负数,则这里的二进制字符串为补码,得在取反的二进制上加一,然后算出十进制数并添加符号。这个过程,我不知道C#中如何实现,希望得到大虾指点.

解决方案 »

  1.   

    使用 Convert.ToInt32 方法 (String, Int32) 将指定基数的数字的 String 表示形式转换为等效的 32 位有符号整数。 命名空间:System
    程序集:mscorlib(在 mscorlib.dll 中)语法
     
    public static int ToInt32 (
    string value,
    int fromBase
    )
     
    参数
    value
    包含数字的 String。 fromBase
    value 中数字的基数,它必须是 2、8、10 或 16。 
    返回值
    等效于 value 中的数字的 32 位有符号整数。 - 或 - 如果 value 为空引用(在 Visual Basic 中为 Nothing),则为零。 --以上摘MSDN
      

  2.   

              string s = "111110010010";
                double res = 0d;
                for (int i = 0; i < 4; ++i)
                {
                    if (s[s.Length - i - 1] == '1')
                        res += ((double)1) / System.Math.Pow(2, (4 - i));
                }            for (int i = 0; i < s.Length - 5; ++i)
                {
                    if (s[s.Length - i - 4 - 1] == '1')
                        res += System.Math.Pow(2 , i);
                }            if (s[0] == '1')
                {
                    res = 0 - res;
                }
      

  3.   

    非常感谢findcaiyzh(秋心)提供的思路。我测了下你提供的代码,如果不含符号位,也就是正数的话,你的代码输出是完全正确的,但是如果是负数的话,这里的二进制字符串是由小数位就开始的补码,而不是单纯的加负号。比如,-55,对应的二进制字符串为"1100 1001 0000",用你的代码转化二来的十进制数为-73。我知道,如果对"1100 1001 0000"取反,得到"001101101111",然后加1,得到"001101110000",这个二进制数用你的代码可以得到55,最后加上负号,就是-55,但是这个取反,然后由就 2的-4次冥 这一位开始加1的过程,不知道该怎么实现。我正在处理一个温度传感器传来的温度值,这些带符号带小数的字符串是由传感器获得的,希望大虾能继续指点。
      

  4.   


            static double GetDoubleFromString(string input)
            {
                bool negative = false;
                if (input[0] == '1')
                {
                    negative = true;
                    StringBuilder sb = new StringBuilder();
                    foreach (char c in input)
                        sb.Append(c == '0' ? "1" : "0");
                    input = Convert.ToString(Convert.ToInt32(sb.ToString(), 2) + 1, 2).PadLeft(input.Length, '0');
                }
                string integers = input.Substring(1, input.Length - 5);
                double result = Convert.ToInt32(integers, 2);
                for (int i = input.Length - 4; i < input.Length; i++)
                {
                    if (input[i] == '1')
                        result += Math.Pow(2, -(input.Length - i));
                }
                return negative ? -result : result;
            }
      

  5.   

    问题终于解决了,在参考了 ojlovecd(本命大限在田宅宫化忌) 和 findcaiyzh(秋心)的代码后,终于将温度准确的转化过来了,谢谢各位大虾的指点。最后我想补充的是,findcaiyzh(秋心)在计算正数时是对的,ojlovecd(本命大限在田宅宫化忌) 则提供给我了思路,但含小数时循环计算有误。我借鉴了 ojlovecd(本命大限在田宅宫化忌) 的代码,和 findcaiyzh(秋心)计算小数的循环。最后,我将 温度传感器 提供的测试用值和修改后代码贴出,并将分数均分给2位大虾,感谢你们了。  温度                        对应二进制补码
    +125°C                   0111 1101 0000
    +85°C                    0101 0101 0000
    +25.0625°C               0001 1001 0001
    +0.5°C                   0000 0000 1000
    -25.0625°C               1110 0110 1111
    -55°C                    1100 1001 0000static double GetDoubleFromString(string input)
            {
                bool negative = false;            int  iLength  = input.Length;            if (iLength == 0)
                {
                    return 0.00;
                }            if (input[0] == '1')
                {
                    StringBuilder sb = new StringBuilder();                negative = true;                foreach (char c in input)
                    {
                        sb.Append(c == '0' ? "1" : "0");
                    }                                //input = Convert.ToString(Convert.ToInt32(sb.ToString(), 2) + 1, 2).PadLeft(input.Length, '0');                for (int i = iLength; i > 0; i--)
                    {
                        if (sb[i - 1] == '0')
                        {
                            sb[i - 1] = '1';                        break;
                        }
                        else
                        {
                            sb[i - 1] = '0';
                        }
                    }                input = sb.ToString();
                }            string integers = input.Substring(1, iLength - 5);            double result = Convert.ToInt32(integers, 2);            for (int i = 0; i < 4; ++i)
                {
                    if (input[iLength - i - 1] == '1')
                    {
                        result += Math.Pow(2, -(4 - i));
                    }                    
                }            //for (int i = iLength - 4; i < iLength; i++)
                //{
                //    if (input[i] == '1')
                //    {
                //        result += Math.Pow(2, -(iLength - i));
                //    }                    
                //}            return negative ? -result : result;
            }
      

  6.   

    从这帖子可以看出,楼主和楼上回帖的,没有一个懂位运算。用位运算计算这个问题很简单string[] list = { 
        "011111010000",
        "010101010000",
        "000110010001",
        "000000001000",
        "111001101111",
        "110010010000"
    };
    foreach (string i in list)
    {
        double n = 0;
        if (i[0] == '1')
        {
            n -= Convert.ToInt32(i.Substring(1, 7), 2) ^ 127;
            n -= ((Convert.ToInt32(i.Substring(8, 4), 2) ^ 15) + 1) / 16.0;
        }
        else
        {
            n += Convert.ToInt32(i.Substring(1, 7), 2);
            n += Convert.ToInt32(i.Substring(8, 4), 2) / 16.0;
        }
        Console.WriteLine(n);
    }
    Console.ReadKey();