搜索
bottom↓
回复: 12

急问:ICCAVR中长整型数据的问题

[复制链接]

出0入0汤圆

发表于 2012-11-4 16:23:40 | 显示全部楼层 |阅读模式
本帖最后由 lanpad 于 2012-11-4 16:30 编辑


程序中有很大的数需要用到32位的无符号长整型数


写了一个测试程序:
uchar compute(uint data)//ulint compute(uint data)
{
        unsigned long  result;
        uchar r1,r2,r3,r4;
       
        result = data*(data+1);
       
        r1 = result;
        r2 = (result>>8);
        r3 = (result>>16);
        r4 = (result>>24);
       

        return(r3);
       
       
}


结果r1、r2可以正常返回计算所得的值
r3、r4的返回值全是0x00,


难道ICCAVR不支持32位的运算,不过我看了Help里Data Type Sizes

TYPE        SIZE (bytes)        RANGE
unsigned char        1        0..255
signed char        1        -128..127
char (*)        1        0..255
unsigned short        2        0..65535
(signed) short        2        -32768..32767
unsigned int        2        0..65535
(signed) int        2        -32768..32767
pointer        2        N/A
unsigned long        4        0..4294967295
(signed) long        4        -2147483648..2147483647
float        4        +/-1.175e-38..3.40e+38
double        4        +/-1.175e-38..3.40e+38

应该是支持的呀

可为什么数据计算结果高16位始终为0呢?


头文件添加了以下这些:

#include <iom128v.h>
#include <macros.h>
#include <limits.h>

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-11-4 16:23:41 | 显示全部楼层
uchar Computer(uint data)
{
        ulong result;
        uchar r1,r2,r3,r4;
        result = (ulong)(data)*(data+1);
        r1 = (uchar)(result);
        r2 = (uchar)(result>>8);
        r3 = (uchar)(result>>16);
        r4 = (uchar)(result>>24);
        return (r3);
}
楼主试试这样行不行

出0入0汤圆

发表于 2012-11-4 17:17:23 | 显示全部楼层
result = (ulong)( data*(data+1);
这是关键。

出0入0汤圆

发表于 2012-11-4 17:19:42 | 显示全部楼层
这样应该就可以了:
  1. uchar compute(uint data)//ulint compute(uint data)
  2. {
  3.         unsigned long result = data;
  4.         uchar r1,r2,r3,r4;
  5.         
  6.         result *= data+1;
  7.         
  8.         r1 = result;
  9.         r2 = (result>>8);
  10.         r3 = (result>>16);
  11.         r4 = (result>>24);
  12.         
  13.         return(r3);
  14. }
复制代码
问题应该是在乘法运算——两个int相乘,结果依然为int,所以高位运算结果由于编译器的截断而丢失。

出0入0汤圆

 楼主| 发表于 2012-11-4 17:52:47 | 显示全部楼层
本帖最后由 lanpad 于 2012-11-4 20:53 编辑

多谢诸位
关键就是少了一个强制类型转换,加上就好了
我后来也试了一下
或者将函数中的形参改为长整型也可以:

uchar compute(uint data)
改为uchar compute(ulong data)


但又有一个问题:

将compute计算的结果通过return返回,在另一个函数中赋给另一个值时,却只能传递低16位,高16位为0:

uint cord;//全局变量

uchar compute(uint data)//ulong compute(uint data)
{
        unsigned long  result;
        uchar r1,r2,r3,r4;
        
        result = (ulong)data*(data+1);
         
        return(result);      
      
}

ulong trans()
{
      ulong d_tr;

      dtr = (ulong) compute(cord);//

}

dtr 本来应该等于0xAF9D1234,可是现在却是0x1234

为何传递的过程不对呢?
强制类型转换(ulong)已经到处加试过了

出0入0汤圆

发表于 2012-11-4 18:24:01 | 显示全部楼层
好奇的问下 computer函数原型是什么?
uchar compute(uint data)是这个
ulong compute(uint data)还是这个?

出0入0汤圆

 楼主| 发表于 2012-11-4 19:13:59 | 显示全部楼层
yklstudent 发表于 2012-11-4 18:24
好奇的问下 computer函数原型是什么?
uchar compute(uint data)是这个
ulong compute(uint data)还是这个 ...

这个都试过,ms对于compute的计算结果没有影响

出0入0汤圆

发表于 2012-11-4 20:27:09 | 显示全部楼层
lanpad 发表于 2012-11-4 19:13
这个都试过,ms对于compute的计算结果没有影响

哎 估计你对C了解不多 还需要多补充这发面的知识

出0入0汤圆

 楼主| 发表于 2012-11-4 20:54:47 | 显示全部楼层
yklstudent 发表于 2012-11-4 20:27
哎 估计你对C了解不多 还需要多补充这发面的知识

一直在补充

可现在改成 ulong compute 还是不对

出0入0汤圆

发表于 2012-11-4 21:14:57 | 显示全部楼层
lanpad 发表于 2012-11-4 20:54
一直在补充

可现在改成 ulong compute 还是不对

ulong Computer(uint dat)
{
    ulong result;
    uchar r1,r2,r3,r4;
    result = (ulong)(dat)*(dat+1);
    r1 = (uchar)(result);
    r2 = (uchar)(result>>8);
    r3 = (uchar)(result>>16);
    r4 = (uchar)(result>>24);
    return (result);
}
在C51平台下测试 是没问题的
ICC不会软件仿真 电脑耶没法运行ICC软件
所以不知道,不过觉得程序应该是米问题的

出0入0汤圆

 楼主| 发表于 2012-11-4 21:30:48 | 显示全部楼层
本帖最后由 lanpad 于 2012-11-4 21:32 编辑

这是完整的测试程序,是在单片机上运行的:

#include <iom128v.h>
#include <macros.h>
#include <limits.h>
#include "parme.h"

#define uchar unsigned char      //定义无符号字符为 uchar
#define uint  unsigned int       //定义无符号整型
#define ulong unsigned long

uint cord = 53326;;//全局变量

ulong trans()
{
   ulong dtr;

   dtr = (ulong)compute(cord);//
   
   usart0_char_send(dtr>>24);/////通过单片机串口返回计算结果观察
   usart0_char_send(dtr>>16);/////通过单片机串口返回计算结果观察
   usart0_char_send(dtr>>8);/////通过单片机串口返回计算结果观察
   usart0_char_send(dtr);/////通过单片机串口返回计算结果观察
}

ulong compute(uint data)//test
{
ulong result;

result = (ulong)data*(ulong)(data+1);

return(result);

}


main()
{
  trans();

}



这个例子中的计算结果应当是53326*53327=0xA97FA812;

可串口返回的结果是:0xFF 0xFF 0xA8 0x12

高16位全变成了1

出0入0汤圆

发表于 2012-11-4 22:35:55 | 显示全部楼层
本帖最后由 yklstudent 于 2012-11-4 22:39 编辑

换了个XP电脑 试了试程序
程序是没有问题的
估计还是你自己写的有点问题

#include <iom128v.h>
#include <macros.h>
#include <limits.h>
#include "parme.h"

#define uchar unsigned char      //定义无符号字符为 uchar
#define uint  unsigned int       //定义无符号整型
#define ulong unsigned long

uint cord = 53326;;//全局变量

void trans()
{
    ulong dtr;
uchar r1,r2,r3,r4;
   dtr = compute(cord);//
    r1 = (uchar)(dtr>>24);
    r2 = (uchar)(dtr>>16);
    r3 = (uchar)(dtr>>8);
    r4 = (uchar)(dtr);
    usart0_char_send(r1);/////通过单片机串口返回计算结果观察
    usart0_char_send(r2);/////通过单片机串口返回计算结果观察
    usart0_char_send(r3);/////通过单片机串口返回计算结果观察
    usart0_char_send(r4);/////通过单片机串口返回计算结果观察
}

ulong compute(uint data)//test
{
ulong result;

result = (ulong)(data)*(data+1);

return(result);

}


main()
{
   trans();

}


试试这个改过得怎么样

出0入0汤圆

 楼主| 发表于 2012-11-5 09:51:07 | 显示全部楼层
还是不行,
看来是return有问题,估计是编译器或硬件平台的原因
最后定义成全局变量算是解决了,只能这么将就这了:


#include <iom128v.h>
#include <macros.h>
#include <limits.h>

#define uchar unsigned char      //定义无符号字符为 uchar
#define uint  unsigned int       //定义无符号整型
#define ulong unsigned long

uint cord = 53326;//全局变量

ulong result;//全局变量





void trans()
{
    ulong dtr;
    uchar r1,r2,r3,r4;
    compute(cord);//
    dtr = result;

    r1 = (uchar)(dtr>>24);
    r2 = (uchar)(dtr>>16);
    r3 = (uchar)(dtr>>8);
    r4 = (uchar)(dtr);
    usart0_char_send(r1);/////通过单片机串口返回计算结果观察
    usart0_char_send(r2);/////通过单片机串口返回计算结果观察
    usart0_char_send(r3);/////通过单片机串口返回计算结果观察
    usart0_char_send(r4);/////通过单片机串口返回计算结果观察
}

ulong compute(uint data)//test
{
//        ulong result;

result = ((ulong)data) * (((ulong)data) + 1);

//        return(result);

}


void  main()
{
  init_devices();


  trans();


   
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表