![](/img/trans.png)
[英]given Integer n and Double x. Calculate: sin x + sinsin x +...+sinsin...sinx. Where n— number of sin
[英]Finding a nonzero integer x where x == -x?
在我大學的算法和數據結構課程中,我收到了這個問題:
哪個整數與其負值具有相同的位模式?
意思是:x == -x
我知道0有效,但我懷疑教練正在尋找其他數字x。 它是什么x? 你怎么會找到它?
Integer.MIN_VALUE和Long.MIN_VALUE沒有等效的正值,當你取這些值的負值時,你會得到相同的值。
負與翻轉所有位並添加一個相同。 即
-x = ~x + 1
所以-0x80000000 = 0x7fffffff + 1 = 0x8000000
注意:Math.abs(Integer.MIN_VALUE)== Integer.MIN_VALUE為負數。 這個方法的javadoc概述了這一點。
從技術上講,有很多答案和類型
byte x = 0;
short x = 0;
char x = 0;
int x = 0;
int x = Integer.MIN_VALUE;
float x = 0.0f;
float x = -0.0f;
long x = 0;
long x = Long.MIN_VALUE;
double x = 0.0;
double x = -0.0;
Byte x = 0;
Short x = 0;
Character x = 0;
Integer x = 0;
Integer x = Integer.MIN_VALUE;
Float x = 0.0f;
Float x = -0.0f;
Long x = 0L;
Long x = Long.MIN_VALUE;
Double x = 0.0;
Double x = -0.0;
類似的Java Puzzler是; 以下表達式何時為true
。
x != x + 0
編輯:浮點數同時為+0.0
和-0.0
。 這樣你可以考慮-0.0
與0.0
的不同值,盡管是-0.0 == -(-0.0)
注意: Double.compare(0.0, -0.0) > 0
注意:
假設您采用帶符號二進制補碼格式的最低可表示數字。 假設這個數字(稱之為x)具有位模式100000...0
,例如。 要計算-x,首先將所有位翻轉到01111...1
,然后再加1。 這會導致較大的紋波進位導致數字1000....0
,這是您開始使用的數字。 因此,您將擁有x == -x
。 在Java int的情況下,此值為Integer.MIN_VALUE
,即-2 31 。
你可以用數學方法解決這個問題。 由於有符號二進制補碼格式的所有數字都以兩個冪(例如,2 d )的模數表示,因此該語句
x == -x
真正意思
x == -x(mod 2 d )
這意味着
2x == 0(mod 2 d )
因此,該問題的解決方案是所有數字x的集合,其中2x是0 mod 2 d 。 這些是任何整數k的形式k× 2d的數字。 這些值中只有兩個可以用帶符號的二進制補碼格式表示,其中d + 1位,即0和-2 d 。 因此,最小可能的負數將始終與其負值相等。
希望這可以幫助!
對於8位整數: 1000 0000
簽名,這是-128而無符號時這是128
另一種方式:所有已簽名的原始整數類型表示范圍內的整數
-2 N-1至2 N-1 -1
(包括),其中N是位數。 每當執行任何數學整數運算時,如果數學結果是某個數字Z超出該范圍(“溢出”),那么實際結果將是R = Z + 2 N * k,其中k是某個正整數或負整數選擇使得R將在-2 N-1到2 N-1 -1的范圍內。所以說x = -2 N-1 ,我們計算-x。 數學結果是Z = 2 N-1 ,但是這超出了范圍,因為Z> 2 N-1 -1。 因此,要使其在范圍內,我們需要為某些k添加2 N * k,並且k必須為-1。 因此,實際結果是R = 2 N-1 +(2 N )*( - 1)= 2 N-1 -2 N = -2 N-1 ,這是x的原始值。 所以這是一個使x == -x的值。
Java只簽署了整數類型,但在具有無符號類型的語言中,無符號類型的范圍是0到2 N -1(包括0和2 N -1)。 但其他一切都以同樣的方式適用。
如上所述,問題含糊不清。
0
當然是顯而易見的解決方案,正如其他人所討論的那樣,Java中沒有其他解決方案(問題是如何被標記的)。
在C中,對於任何有符號整數類型,給定類型的最小值可以是某些實現的解決方案。 例如,給定2的補碼表示,評估-INT_MIN
可能會給你-INT_MIN
。 但事實上,即使你假設2的補碼,由於溢出,評估該表達式的行為也是未定義的 。 (環繞語義很常見,但不保證。)此外,C標准不需要二進制補碼表示; 它還允許1的補碼和符號和幅度,這兩者都沒有額外的負值。
這個程序:
#include <stdio.h>
#include <limits.h>
int main(void) {
int n = INT_MIN;
printf("%d\n%d\n", n, -n); /* Warning: Undefined behavior for -n */
}
在我的系統上生成此輸出:
-2147483648
-2147483648
C無符號類型的操作具有更嚴格定義的行為。 這個程序:
#include <stdio.h>
#include <limits.h>
int main(void) {
unsigned int n = UINT_MAX / 2 + 1;
printf("%u\n%u\n", n, -n);
}
在具有32位int
(並且沒有填充位)的系統上提供此輸出:
2147483648
2147483648
並將在任何符合要求的實現上打印兩行相同的輸出。
C ++在此區域中具有與C相同的行為(或未定義的行為)。
在Perl中,如果一個大整數太大而不能表示為一個整數,那么它將落在一個浮點表示中 - 但Perl標量很復雜,並且可以同時存儲多個表示。 在我的64位系統上,這個Perl程序:
#!/usr/bin/perl
use strict;
use warnings;
my $n = -2.0**63;
print $n, "\n", -$n, "\n";
printf "%d\n%d\n", $n, -$n;
給出這個輸出:
-9.22337203685478e+18
9.22337203685478e+18
-9223372036854775808
-9223372036854775808
我不完全確定我能解釋自己。
Python似乎回退到某種形式的擴展精度整數,因此不會出現溢出問題,因此沒有數值是它自己的否定。 許多其他語言(包括,我認為,大多數Lisp方言)都做同樣的事情。
在Ada中,整數溢出沒有未定義的行為; 需要提出異常。 這個程序:
with Ada.Text_IO; use Ada.Text_IO;
procedure Foo is
N: Integer := Integer'First;
begin
Put_Line(Integer'Image(N));
Put_Line(Integer'Image(-N));
end Foo;
只產生一行輸出:
-2147483648
然后死於Constraint_Error
異常。
等等,等等......
因此,除非教師只是尋找零作為答案,否則它在很大程度上取決於上下文。
看看這個問題,為什么你會假設0
(這是一個完全正確和明顯的答案,如同所寫的問題,顯然是Java中唯一正確的答案)不是教師所尋求的?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.