精华内容
下载资源
问答
  • 强转

    2019-09-09 16:07:16
    强转、 比如说double 转为 int 的时候可能会造成精度丢失。 这里的精度丢失,是把小数点后的数直接砍掉。比如:3.444 直接转为 3

    强转、  比如说double  转为 int 的时候可能会造成精度丢失。

    这里的精度丢失,是把小数点后的数直接砍掉。比如:3.444 直接转为 3

    展开全文
  • float强转int

    万次阅读 2018-06-24 10:24:23
    推荐阅读关于float转int的函数实现(非结构体实现版)类型强转丢失精度的根源 目录 一、思路 1.1 十进制 1.2 二进制 1.3 处理棘手的符号位 1.4 小端模式 二、C语言实现 2.1 思路 2.2 利用结构体实现 2.3 ...

    本文只讨论float转int的原理,如有不当之处,欢迎留言指出。交流学习。 

    推荐阅读关于float转int的函数实现(非结构体实现版) 类型强转丢失精度的根源

    目录

    一、思路

    1.1 十进制

    1.2 二进制

    1.3 处理棘手的符号位

    1.4 小端模式

    二、C语言实现

    2.1 思路

    2.2 利用结构体实现

    2.3 利用内存拷贝函数memcpy实现


    一、思路

    1.1 十进制

    大体和科学计数法(小数点前面只有1位,和用什么进制实现没有关系)别无二致。如果十进制:

    图1 十进制下的科学计数法

    从图1 我们可以看到, 对于科学计数法而言,小数点前面只有1位、小数点后面是有效位、以10为底数的幂有正有负有0。那么为了记录一个十进制数,我们需要记录四个要素:符号、小数点前的一位、有效位、指数。

    1.2 二进制

    类比到二进制,小数点前面一位一定是1,正如十进制小数点前面一位一定是1-9一样;那么我们只需记录符号有效位以及指数。下面我们先举一个例子:-12,25展成float。注意:此处不要去想表示整型的原码反码补码那一套了。正如稍前讨论的那般,指数是有正负的,那如果不加某种手段,如何表示指数的正负呢?

    1.3 处理棘手的符号位

    IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985)告诉我们一个很棒的解决办法:是这样做的,选取8bite用于表示指数部分(底数是2),有256种变化,既可以理解为0-255也可以理解为-128-127,取决于设计者是如何去解释的。而后者是非常好的,正指数和负指数都是127一人一半。所以不管实际指数是多少,一律加上127类似于加密过程;等到想把真实值取出来的时候,一律减去127类似于解密过程。

    现在来演算一下-12.25如何展成float吧:

    图2 -12.25展成float

    最后我们才能大体看懂这张示意图:

    图3 float类型结构示意图

    1.4 小端模式

    大端模式和小端模式的由来

    二、C语言实现

    2.1 思路

    难点在于如何用一个变量去读出内存中存放的float类型的变量。最直接的办法就是按照float类型的结构去设计一个完全一致的结构体,更为巧妙的办法是将float类型的变量通过调用内存拷贝函数memcpy复制到unsigned long类型的变量中。这两种办法都能将float类型的变量取出,然后分别读取符号位、指数位、尾数有效位。

    学无止境,下面分别讨论这两种思路的实现:

    2.2 利用结构体实现

    用到了位域的知识点:

    图4 单词mantissa

    结构体设计以及函数声明。

    #include<stdio.h> //printf()
    #include<stdlib.h> //atof()
    
    typedef struct FloatNode
    {
        unsigned int mantissa : 23; //尾数部分
        unsigned int exponent : 8; //指数部分
        unsigned int sign : 1;  //符号位
    }FloatNode;
    
    int GetSign(const FloatNode *fn); //获取符号位
    int GetExp(const FloatNode *fn); //获取指数部分
    int Float_To_Int(float num); //类型强制转换

    其他函数的实现

    int GetSign(const FloatNode *fn) //获得符号位
    {
        return fn->sign == 1 ? -1 : 1;
    }
    
    int GetExp(const FloatNode *fn) //获得指数位
    {
        return (fn->exponent - 127); //根据IEEE754,减去127才是真正的指数位
    }
    
    int Float_To_Int(float num) //将float强转成int
    {
        FloatNode *fn = (FloatNode*)&num;
        int exp = GetExp(fn);
    
        if(exp >= 0)
        {
            int mov = 23 - exp;
            int res = (fn->mantissa | 1<<23) >> mov;
            return res*GetSign(fn);
        }
        else
        {
            return 0;
        }
    }

    main主函数

    int main(int argc, char* argv[])
    {
        if(argc <= 1)
        {
            printf("%s\n", "Argument isn't enough.");
            return 0;
        }
        char *p = argv[1];
        float num = atof(p);
        int res = Float_To_Int(num);
        printf("转换之后的结果是:%d\n", res);
        return 0;
    }
    图5 linux下运行结果

    2.3 利用内存拷贝函数memcpy实现

    重要的话,浮点型没有移位运算,或者说,即使强行进行移位运算也是被当成整型对待而得到错误的结果。如果不用一个和float类型完全一致的结构体去读取,那么只能将float类型的数据放到unsigned类型中再进行操作。

    实际上就是对float型的结构进行解析,尤要注意的是运算符的优先级,告诫本篇博客的博友们:不要止步于看懂,自己也要写一写。

    库文件的引入及函数的声明:

    #include<stdio.h> //printf()
    #include<string.h> //memcpy()
    #include<stdlib.h> //atof()
    
    int getSign(unsigned num);      //获得符号位
    int getExp(unsigned num);       //获得指数部分
    int float2int(float ft);    //float强转为int

    其他函数的实现

    int getSign(unsigned num)       //获得符号位
    {
        int sign = num & (1<<31);
        return sign == 0 ? 1 : -1; 
    }
    
    int getExp(unsigned num)        //获得指数部分
    {
        int exp = 0;
        for(int i = 23; i < 31; ++i)
            exp |= (num & (1<<i));
        exp = (exp>>23) - 127;
        return exp;
    }
    
    int float2int(float ft) //float强转为int
    {
        unsigned num;
        memcpy(&num, &ft, sizeof(float)); //将float数据完整地拷贝到unsigned中
    
        int exp = getExp(num); //获得float存储结构的指数部分
        if(exp < 0) //如果指数小于0的话,实际值肯定是0.***,故而强转之后就为0
        {
            return 0;
        }
        else
        {
            int res = num & ((1<<23)-1);  //保留mantissa 注意运算符的优先级
            res |= 1<<23;   //将小数点前的1补上
            res >>= (23-exp); //整数部分右移到合适位置
            return res*getSign(num);
        }
    }

    main主函数

    int main(int argc, char * argv[])
    {
        if(argc <= 1)
        {
            printf("augument is not enough.\n");
            return 0;
        }
    
        float ft = atof(argv[1]); //将字符串转化为同值的float
        int res = float2int(ft);
        printf("转换之后的结果是:%d\n", res);
        return 0;
    }

    运行结果:

    图6 linux下运行结果
    展开全文
  • JAVA 强转强转

    2020-05-02 10:10:52
    通常我们遇到的强转,最为常见的是: long a = 1L; int b = (int) a; 这种基本类型的强转会损失一定精度。 那么非基本数据类型能否强转吗? 当然也可以,比如下面两个类。 class User{ } class BigUser ...

    通常我们遇到的强转,最为常见的是:

    long a = 1L;
    int b = (int) a;

    这种基本类型的强转会损失一定精度。

    那么非基本数据类型能否强转吗?

    当然也可以,比如下面两个类。

    class User{
    }
    class BigUser extends User{
        boolean big;
    }

     

    我们测试一番,使用main方法调用test方法:

    void main(){
        test(new BigUser());
    }
    
    void  test(User user){
        BigUser bu = (BigUser)user;
        ...
    
    }

    运行起来是不报错的,

    但是需要注意的是,我们看test方法里,只有user对象本质上就是BigUser时,才会强转成功,否则会报ClassCastException

    比如下面的例子,就会报错:

    void main(){
        test(new User());
    }
    
    void  test(User user){
        BigUser bu = (BigUser)user;
        ...
    
    }

    有时候我在写一些基础构件时,会希望能够这样强转,那样的话就不用copy属性等数据了..但目前java是不支持的.它会报错.

    展开全文
  • 关于强转

    2021-01-19 14:34:39
    先贴一段代码 Person p1=new Student(); Person p2=new Person();...可以自行思考一下,哪一行会出现强转的错误。 答案是最后一行。 因为变量p1指向的是Student类型(向下转型),所以它可以强转为Stu

    先贴一段代码

    		Person p1=new Student();
            Person p2=new Person();
            Student s1=(Student)p1;
            Student s2=(Student)p2;
    

    Person是父类,Student是子类,代码不报任何错误,不过运行之后会报ClassCastException。可以自行思考一下,哪一行会出现强转的错误。

    答案是最后一行。
    因为变量p1指向的是Student类型(向下转型),所以它可以强转为Student类型。但是变量p2指向的是Person类型,所以它强转成Student类型时会报错。因为Student是子类,它的功能可能会比父类多,而这些多出来的功能不能靠父类去凭空想象,所以强转会失败。
    如何避免强转错误呢?这就用到了instance of。

    Person p = new Student();
    if (p instanceof Student) {
        // 只有判断成功才会向下转型:
        Student s = (Student) p; // 一定会成功
    }
    

    在需要使用向下转型的时候,加一个instance of判断,就可以很好的避免强转失败的错误

    展开全文
  • 数据强转

    2019-02-26 17:19:00
    数据类型强转 一般都是转成STRING NUMBER BOOLEAN 调用方法tostring() 该方法不会改变原数据类型,只是会将强转后的类型返回 所以一般用新的变量去接收它 调用函数 string() 字符串转换成数字 如果有非数字的...
  • 强转溢出

    2019-10-17 19:39:02
    //类型转换 int a=200; byte b=127; //大类型强转小类型 //快捷键alt+enter b= (byte) a; System.out.println(b); 溢出 -56
  • byte与string底层强转

    2021-01-20 13:57:01
    普通强转 用关键字进行强转,底层会发生拷贝,两个变量互不影响。 代码示例: s:=012345 b:=[]byte(s) s1:=string(b) fmt.Println(s1) b[0]='9' fmt.Println(s1) === RUN Test_强转 012345 012345 --- PASS: ...
  • 当使用带括号的强转时,如果当前对象无法转成目标对象则会直接报错 当使用as强转时,如果当前对象无法转成目标对象则会返回一个null 总结,as是相对温和的转换形式,使用as转换时要注意做返回值是否为空的安全校验 ...
  • 关于强转

    2020-12-18 11:11:30
    今天遇到个怪异的问题 我的 map 的key 确定是 Integer型的,怎么会报这个异常呢? 用arthas 看一下 这个方法返回的Map 的 Key竟然变成了 String 过会儿看一下强转的底层吧。
  • C++类型强转

    2018-11-14 21:57:32
    C类型风格转换(二进制级别的内存拷贝) ... reinterpret_cast转换是四种C++类型强转中和C风格类型强转最接近的,转换完全肆无忌惮,直接从二进制开始重新映射解释。它可以用于任何指针指向任...
  • MYSQL数据库中怎么对字符串进行强转发布时间:2020-12-08 15:14:30来源:亿速云阅读:103作者:LeahMYSQL数据库中怎么对字符串进行强转?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细...
  • map强转list

    2020-04-29 18:05:51
    map.get("key")中包括clob类型转list java.lang.String cannot be cast to java.util.Map map.get("key")对象中是varchar 可以强转 List ret=(List)map.get("key");
  • null 强转对象

    2020-09-18 16:34:01
    记录一次null强转对象的情况。 @Test public void test() { Map<String, Object> map = Maps.newHashMap(); A a = (A)map.get("a"); // A a = (A)null; a.a(); a.b(); System.out.println(111); ...
  • 类型强转—整数有负号强转 注意强制转换要注意类型的精度 大范围转小范围 精度会丢失 强转后为什么是 -1 ?? 为什么丢失数据后是 -72呢 类型强转—整数无负号强转 ...
  • 强转网络接口

    2018-10-25 21:30:11
    // 可以把HTTPS切换成HTTP public static String https2Http(String url) { return url.replace("https", "http"); } ...//强转代码 新创的Util.方法名(icon)强转  
  • 强转直接举例说明:A 表id是int 类型 B表id是 char 类型如果要转为int 则是signed如果要转为char 则是char注意:需转换的类型必须是left join 后表的字段,否则不走索引因为联表字段类型不一致,所以不走索引select ...
  • 指针强转

    2013-05-24 15:09:07
    一级指针强转成二级指针,如void*到char**,用一句话理解,就是把一级指针所指的内存强转成char*. void main() {  void *p = malloc(20);  memset(p,0,20);  char **typed_p = (char **)p;    printf(...
  • string强转int

    万次阅读 2018-03-01 19:52:20
    学艺不精,数次遇到强转问题老是忘记,现在记录下来 有2个方法:1). int i = Integer.parseInt(str); 2). int i = Integer.valueOf(str).intValue();
  • 强转 直接举例说明: A 表id是int 类型 B表id是 char 类型 如果要转为int 则是signed 如果要转为char 则是char 注意:需转换的类型必须是left join 后表的字段,否则不走索引 因为联表字段类型不一致,所以不走索引...
  • C类型强转的理解

    2020-07-13 18:50:36
    其实并不难,只是没有注意到强转的区别。 指针强转:什么都不做修改,只是修改了对地址的边界和对地址中数据的解释。 变量强转:创建一个临时变量,将原数据进行转换到临时变量。所以不能使用&来取变量强转之后...
  • java类型强转

    2017-07-27 13:49:00
    首先基本数据类型不是对象,强转改的是值,分为有损和无损,有损会丢失数据细节。 然后对象,只有继承关系的类才能强转,改变的只是引用,而且向上转型是安全的,把你转为人类是安全的,你还是你,只是现在别人看你...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,591
精华内容 1,836
关键字:

强转