整数类型转换问题/问题 [英] integer type conversion problem/question

查看:69
本文介绍了整数类型转换问题/问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我不确定什么更合适,所以我把它们都绑定到了两个

alt.comp。 lang.learn.c-c ++和comp.lang.python,后跟

alt.comp.lang.learn.c-c ++。


虽然在混合的

Python / C ++编程问题的上下文中使用随机数生成器。我遇到了一个令人烦恼的类型

转换问题。


简单来说,情况如下。


我有Python中的一个整数(Python整数实现为C long

整数)。


这是传递给C ++中的一个函数,它将它(据说)转换为

一个unsigned int,修改它然后将它传递回Python。这个

完成,因为随机数生成器使用无符号整数。


Python尝试将其转换为Python整数,如果它太过

large,将其转换为Python long。 (整数和长整数都是
Python类型)。


现在,我的程序崩溃,因为在某些时候无符号整数
$ b $传递给Python的b变得太长而无法表示为(unsigned)
int,我收到溢出错误。


OverflowError:long int too large转换为int


这样一个数字的一​​个例子是2321871520.Python认为这应该是长的,但是我的C ++代码似乎把它当作一个unsigned int,并且

将它传递给Python。当Python将其转换为long并且

尝试将其传回时,我收到运行时错误。


Python给出:

在[1]中:2321871520

Out [1]:2321871520L

我尝试编译以下代码片段(头部省略)和

有一个编译器警告:警告:这个十进制常数是无符号的

仅在ISO C90中。


我不知道该怎么做这个。


*******************************

int main()

{

unsigned int a = 2321871520;

cout<< a<<结束;

返回0;

}

******************** *************


我发现这一切都有点奇怪。从理论上讲,Python int比B int大
(因为Python int实现为C long int),

应该(理论上)转换C无符号没问题注:

Python整数(对应于C长整数)但在实践中

有。任何人都可以告诉我这个令人费解的情况吗?

谢谢。


我很乐意在必要时提供更多细节。我意识到上面的

可能不完全清楚,但过多的细节可能会令人困惑。

如果有任何回复请CC我。谢谢。


Faheem。

解决方案

>从理论上讲,Python int大于C ints < blockquote class =post_quotes>(因为Python int实现为C long int),


错误的前提。在今天的许多(大多数?)系统中,C long == C int == 32位。

应该(理论上)将C无符号整数转换为Python整数没有问题(对应到C长整数)




因此你得到了错误的结论。无符号C int> 2 ** 31没有

当C long == C int时正确转换为C long。


如果你必须编写自己的RNG,最简单的解决方案是将它限制在范围内

[0,2 ** 31-1]所以签名/未签名无关紧要。


Terry J. Reedy


[搞砸了设置后续行动,抱歉。这次真的设置后续跟踪

alt.comp.lang.learn.c-c ++。]


周六,2004年10月9日06:50:20 GMT,Faheem Mitha< fa **** @ email.unc.edu>写道:



我不确定什么更合适,所以我把它连接到两个
alt.comp.lang .learn.c-c ++和comp.lang.python,后跟
alt.comp.lang.learn.c-c ++。

在上下文中使用随机数生成器混合的Python / C ++编程问题。我遇到了一个棘手的转换问题。




[snip]


感谢Alwyn和Terry Reedy向我解释事情。我想

我理解要点。 Harbison和Steele的'C A参考

手册' (我有第4个Edn)清楚地解释了C

如何实现无符号和签名的整数,包括两个补码和




看起来像使用随机数生成器使用无符号整数

因为它的Python种子可能几乎是不可能的。可以

有人建议一个好的C / C ++随机数实现,这可以用这种方式轻松地用于Python吗?我想要的东西是

全功能,即。对不同的随机数

分布有合理的支持。另外,作为共享库的一部分,已经以合理的方式打包的东西会很好。我想
假设某些东西的种子存储为整数或多头可以工作

好​​的。


我试图使用r- mathlib

http:// packages .debian.org / unstable / math / r-mathlib),Debian

包对应独立的C Mathlib(数学/统计库)

来自R( www.r-project.org)。不幸的是随机数

实现使用无符号整数,因此所有的kerfuffle。我是

包括此消息末尾的源代码,用于记录。


我确实有一个后续问题。如果Python实现其整数为

签署C ints那么肯定2 ^ 31 - 1应该是一个整数而不是

长?但是我得到了


在[9]:2 ** 31 - 1

Out [9]:2147483647L


在[10]中:输入(2 ** 31 - 1)

输出[10]:< type''long''>


感谢您的帮助。

Faheem。


********************** **************************** *********************

src / nmath / standalone / sunif.c

************************** ************************ *********************

/ *

* Mathlib:AC特殊功能库

*版权所有(C)2000,2003 R开发核心团队

*

*此程序是免费软件;您可以根据GNO通用公共许可证的条款重新分发和/或修改

*它由

*自由软件基金会发布;许可证的第2版,或者

*(根据您的选择)以后的任何版本。

*

*此程序在希望它有用,

*但没有任何保证;甚至没有暗示的保证

*适销性或特定用途的适用性。有关更多详细信息,请参阅

* GNU通用公共许可证。

*

*您应该已收到GNU通用公共许可证的副本

*以及该计划;如果没有,请写信给自由软件

* Foundation,Inc.,59 Temple Place,Suite 330,Boston,MA 02111-1307 USA

*

* /


/ * Marsaglia-MultiCarry的一个版本* /

static unsigned int I1 = 1234,I2 = 5678;


void set_seed(unsigned int i1,unsigned int i2)

{

I1 = i1; I2 = i2;

}


void get_seed(unsigned int * i1,unsigned int * i2)

{

* i1 = I1; * i2 = I2;

}

双unif_rand(无效)

{

I1 = 36969 *(I1 & 0177777)+(I1>> 16);

I2 = 18000 *(I2& 0177777)+(I2>> 16);

return( (I1 << 16)^(I2& 0177777))* 2.328306437080797e-10; / *在[0,1)* /

}


2004年10月9日星期六19:31:30 GMT,Faheem Mitha< ; FA **** @ email.unc.edu>写道:

我确实有一个后续问题。如果Python实现其整数为
签署C ints,那么肯定2 ^ 31 - 1应该是整数而不是
多长?但是我得到了

在[9]:2 ** 31 - 1
Out [9]:2147483647L

在[10]中:类型(2 ** 31 - 1)
Out [10]:< type''long''>




对我自己的消息进行迟来的跟进。以下表现如预期。


在[13]:2147483647

Out [13]:2147483647


在[14]:2147483648

Out [14]:2147483648L


显然有一些关于**符号的东西使得Python

认为这很长。由于Python人们更有可能知道答案,所以尽管有后续行动,我仍然在使用comp.lang.python。谢谢。


Faheem。


Hi,

I''m not sure what would be more appropriate, so I''m ccing it to both
alt.comp.lang.learn.c-c++ and comp.lang.python, with followup to
alt.comp.lang.learn.c-c++.

While working with a random number generator in the context of a mixed
Python/C++ programming problem. I encountered a vexing type
conversion problem.

Briefly, the situation is as follows.

I have a integer in Python (Python integers are implemented as C long
ints).

This is passed to a function in C++ which converts it (supposedly) to
an unsigned int, modifies it and then passes it back to Python. This
is done since the random number generator uses unsigned ints.

Python attempts to convert it to a Python integer, and if it is too
large, converts it into a Python long. (Both integer and long are
Python types).

Now, my program crashes, because at some point the unsigned integer
passed to Python becomes too long to be represented as an (unsigned)
int, and I get an overflow error.

OverflowError: long int too large to convert to int

An example of such a number is 2321871520. Python thinks this should
be a long, but my C++ code seems to handle it as an unsigned int, and
passes it to Python as such. When Python converts it to a long and
tries to pass it back, I get a runtime error.

Python gives:

In [1]: 2321871520
Out[1]: 2321871520L
I tried compiling the following fragment of code (header ommitted) and
got a compiler warning: warning: this decimal constant is unsigned
only in ISO C90.

I''m not sure what to make of this.

*******************************
int main()
{
unsigned int a = 2321871520;
cout << a << endl;
return 0;
}
*********************************

I find all this a little strange. Since in theory Python ints are
larger than C ints (since Python ints are implemented as C long ints),
there should be (in theory) no problem converting C unsigned ints to
Python integers (corresponding to C long integers) but in practice
there is. Can anyone enlighten me as to this puzzling situation?
Thanks.

I''d be happy to give more details as necessary. I realise the above
may not be entirely clear, but excessive detail may be confusing.
Please CC me on any reply. Thanks.

Faheem.

解决方案

>Since in theory Python ints are larger than C ints

(since Python ints are implemented as C long ints),
Wrong premise. On many (most?) systems today, C long == C int == 32 bits.
there should be (in theory) no problem converting C unsigned ints to
Python integers (corresponding to C long integers)



Hence wrong conclusion, as you discovered. Unsigned C int > 2**31 does not
convert properly to C long when C long == C int.

If you must program your own RNG, simplest solution is to limit it to range
[0, 2**31-1] so signed/unsigned does not matter.

Terry J. Reedy


[Screwed up setting the followup, sorry. Really setting followups to
alt.comp.lang.learn.c-c++ this time.]

On Sat, 09 Oct 2004 06:50:20 GMT, Faheem Mitha <fa****@email.unc.edu> wrote:

Hi,

I''m not sure what would be more appropriate, so I''m ccing it to both
alt.comp.lang.learn.c-c++ and comp.lang.python, with followup to
alt.comp.lang.learn.c-c++.

While working with a random number generator in the context of a mixed
Python/C++ programming problem. I encountered a vexing type
conversion problem.



[snip]

Thanks to Alwyn and Terry Reedy for explaining things to me. I think
I understand the main points. Harbison and Steele''s "C A Reference
Manual" (I have the 4th Edn) had a clear explanation of how C
implements unsigned and signed ints, including two''s complement and
all that.

It looks like using a random number generator which uses unsigned ints
as its seeds with Python is probably close to impossible then. Can
anyone suggest a good C/C++ random number implementation which can be
used easily with Python in this fashion? I want something that is
full-featured, ie. has reasonable support for different random number
distributions. Also, something that was already packaged in a
reasonable fashion as part of a shared library would be nice. I
suppose something whose seeds are stored as ints or longs would work
Ok.

I was trying to use r-mathlib
(http://packages.debian.org/unstable/math/r-mathlib), the Debian
package corresponding to the standalone C Mathlib (math/stat library)
from R (www.r-project.org). Unfortunately the random number
implementation uses unsigned ints, hence all the kerfuffle. I''m
including the source code at the end of this message, for the record.

I did have one followup question. If Python implements its integers as
signed C ints then surely 2^31 - 1 should be an integer rather than a
long? But I get

In [9]: 2**31 - 1
Out[9]: 2147483647L

In [10]: type(2**31 - 1)
Out[10]: <type ''long''>

Thanks for the help.
Faheem.

************************************************** *********************
src/nmath/standalone/sunif.c
************************************************** *********************
/*
* Mathlib : A C Library of Special Functions
* Copyright (C) 2000, 2003 The R Development Core Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

/* A version of Marsaglia-MultiCarry */

static unsigned int I1=1234, I2=5678;

void set_seed(unsigned int i1, unsigned int i2)
{
I1 = i1; I2 = i2;
}

void get_seed(unsigned int *i1, unsigned int *i2)
{
*i1 = I1; *i2 = I2;
}
double unif_rand(void)
{
I1= 36969*(I1 & 0177777) + (I1>>16);
I2= 18000*(I2 & 0177777) + (I2>>16);
return ((I1 << 16)^(I2 & 0177777)) * 2.328306437080797e-10; /* in [0,1) */
}


On Sat, 09 Oct 2004 19:31:30 GMT, Faheem Mitha <fa****@email.unc.edu> wrote:

I did have one followup question. If Python implements its integers as
signed C ints then surely 2^31 - 1 should be an integer rather than a
long? But I get

In [9]: 2**31 - 1
Out[9]: 2147483647L

In [10]: type(2**31 - 1)
Out[10]: <type ''long''>



Belated followup to my own message. The following behaves as expected.

In [13]: 2147483647
Out[13]: 2147483647

In [14]: 2147483648
Out[14]: 2147483648L

Apparently there is something about the ** notation that makes Python
think of this as a long. Since Python people are more likely to know
the answer, I''m ccing comp.lang.python despite the followup. Thanks.

Faheem.


这篇关于整数类型转换问题/问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆