WP8.1中C++的winodws运行时组件位移操作的差异
最近学习WP8.1应用开发,想把C语言的SM3国密算法移植到手机app中。由于把C语言的代码转换成C#代码工作量较大,因此只能用winodws运行时组件来实现。
SM3国密算法是一种HASH算法,具体详情请自行百度。
结果测试发现手机上SM3算法计算出来的结果和电脑上运行的结果不同!经过我一点点调试发现是位移操作惹的祸,代码中有如下宏定义:
#define SHL(x,n) (((x) & 0xFFFFFFFF) << n)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))
第一行的宏定义当n大于32时,手机运算结果与电脑不同;第二行的宏定义当32-n小于0时,手机运算结果与电脑不同。
为了更好地测试,我决定建一个干净的测试环境。首先新建一个C#语言的空白的windows phone应用项目,在xaml中放一个textblock和2个按钮
<Grid>
<StackPanel>
<TextBlock x:Name="txbResult"/>
<Button x:Name="btnCSharpLeft" Content="C#位移" Click="btnCSharpLeft_Click"></Button>
<Button x:Name="btnCLeft" Content="C左位移" Click="btnCLeft_Click"></Button>
</StackPanel>
</Grid>
再实现按钮点击事件
private void btnCSharpLeft_Click(object sender, RoutedEventArgs e)
{
txbResult.Text += "C#位移\n";
for (int i = ; i < ; i += )
{
string str = "0x12345678<<" + i.ToString() + "=" + (0x12345678 << i).ToString("X");
txbResult.Text += str.PadRight() + "0x12345678>>" + i.ToString() + "=" + (0x12345678 >> i).ToString("X") + "\n";
}
} private void btnCLeft_Click(object sender, RoutedEventArgs e)
{
txbResult.Text += "C位移\n";
Class1 c = new Class1();
for (int i = ; i < ; i += )
{
string str = "0x12345678<<" + i.ToString() + "=" + c.Func2(0x12345678, i).ToString("X");
txbResult.Text += str.PadRight() + "0x12345678>>" + i.ToString() + "=" + c.Func1(0x12345678, i).ToString("X") + "\n";
}
}
接着新建一个C++语言的windows运行时组件,对外提供两个函数,用以实现左位移和右位移
unsigned int Class1::Func1(unsigned int n, int b)
{
return n >> b;
} unsigned int Class1::Func2(unsigned int n, int b)
{
return n << b;
}
然后连上手机进行测试,我的手机是nokia920,公司测试部的测试机,先拿来用用,吼吼!
可以看到C#的位移在超过32时是对32取模的,也就是说位移33位相当于位移1位,而手机上运行结果测试超过32位都是0!
为了确定是否C++语言的位移都是这么处理的,我再新建一个WIN32的控制台项目来测试
#include "stdio.h" int main()
{
printf("C左移\n");
for (int i = ; i < ; i += )
{
printf("0x12345678<<%d = %x\n",i,0x12345678 << i);
}
printf("C右移\n");
for (int i = ; i < ; i += )
{
printf("0x12345678>>%d = %x\n", i, 0x12345678 >> i);
}
return ;
}
运行结果如下
可以看到和C#的结果是一样的。说明只有C++的windows运行时组件中才会有不同的结果。
同理我再测试位移负数位,比如 0x12345678>>-2,在C#和C++的WIN32程序中位移-2位相当于位移30位,而在C++的windows运行时组件中则结果是0。
结论:为了兼容性,位移时要对32取模,比如1>>n要写成1>>(n%32),这样在不同的平台中也能得到相同的结果。
WP8.1中C++的winodws运行时组件位移操作的差异的更多相关文章
- 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容
在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...
- 为什么一定要调用 setlocale 呢? 因为在 C/C++ 语言标准中定义了其运行时的字符集环境为 "C" ,也就是 ASCII 字符集的一个子集。使用setlocal改变整个应用程序的字符集编码方式(wcstombs使用前要设置 setlocale (LC_ALL, "chs"); )
setlocale 配置地域化信息. 语法: string setlocale(string category, string locale); 返回值: 字符串 函数种类: 操作系统与环境 内容 ...
- Windows 运行时组件
Windows 运行时组件是自包含对象,可将其实例化,并可采用任一语言使用它,包括 C#.Visual Basic.JavaScript 和 C++. 你可以使用 Visual Studio 和 C# ...
- win7下无法安装QTP-少了Microsoft Visual c++2005 sp1运行时组件
问题是:当我点击QTP的setup.exe进行QTP安装时,出现提示[少了Microsoft Visual c++2005 sp1运行时组件,安装时会提示命令行选项语法错误,键入“命令/?”可获取帮肋 ...
- Java中获取类的运行时结构
获取运行时类的完整结构 通过反射获取运行时类的完整结构 Field(属性).Method(方法).Constructor(构造器).Superclass(父类).Interface(接口).Annot ...
- 用系统工具sxstrace检查缺少的VC运行时组件
在管理员运行的命令提示符中输入sxstrace获得如下帮助: C:\>sxstrace WinSxs Tracing Utility. Usage: SxsTrace [Options] Opt ...
- vb 中recordset提示对象关闭时不允许操作
vb中执行查询后,一般要判断是否为空,只要执行的查询执行了select,都可以用rs.eof 或者 rs.recordcount来判断, 但是,如果执行的sql中加了逻辑判断,导致没有执行任何sele ...
- 内核运行时数据结构的操作(启用路由功能),sysctl内核设置命令
LINUX系统运行时,内核数据结构数据的修改,系统提供了统一抽象的文件操作接口(命名空间操作接口)比如启用路由功能echo 1 > proc/sys/net/ipv4/ip-forward// ...
- 安装LR11 时,安装Microsoft Visual c++2005 sp1运行时组件,就会提示命令行选项语法错误,键入“命令/?”可获取帮肋信息
1.进入loadrunner-11\Additional Components\IDE Add-Ins\MS Visual Studio .NET 2.安装:LRVS2005IDEAddInSetup ...
随机推荐
- Linux 折腾汇集,实时更新
一.Linux教程 入门教程:http://www.92csz.com/study/linux/ 命令大全:http://man.linuxde.net/ 一.界面: 在Ubuntu.Linux Mi ...
- JavaScript Patterns 6.6 Mix-ins
Loop through arguments and copy every property of every object passed to the function. And the resul ...
- 用struts和hibernate结合MVC层实例
1.倒包hibernate11个包+sturts2 13个包 2.创建web.xml <?xml version="1.0" encoding="UTF-8&quo ...
- A record--Offline deployment of Big Data Platform CDH Cluster
A record--Offline deployment of Big Data Platform CDH Cluster Tags: Cloudera-Manager CDH Hadoop Depl ...
- js日期校验
当查询条件含有日期时,如"2012-3-4",查询前校验输入的日期字符串是否为有效的日期 var snapshot_createTime_begin=$(selector+&quo ...
- 如何让django方法自动地定期执行
实现思路:1.首先把需要自动执行的django method写成django command2.将自己定义的django command添加到cron中使用cron服务实现定期执行 Part1 在dj ...
- 周一干不干活-PHP+MySQLi
hi 本来是雄心壮志的要干活的,哪知天有不测,早上大阴天起不来,中午又回寝室折腾衣服(做女工啊,牛不牛)没睡午觉,这样的迷糊状态,怎么科研,写这个好了. 1.PHP的OOP编程 4.7 多态 --定义 ...
- 32-bit ALU [Verilog]
Based on MIPS Instruction Structure Main Module module Alu( input [31:0] a, // operand 1 input [31:0 ...
- Codeforces Round #371 (Div. 2) C. Sonya and Queries[Map|二进制]
C. Sonya and Queries time limit per test 1 second memory limit per test 256 megabytes input standard ...
- CF 672C Recycling Bottles[最优次优 贪心]
C. Recycling Bottles time limit per test 2 seconds memory limit per test 256 megabytes input standar ...