숫자가 양수인지 음수인지 확인하는 방법은 무엇입니까?
인터뷰에서 숫자가 양수인지 음수인지 확인하는 방법에 대해 질문을 받았습니다. 규칙은 우리가 같은 조건 연산자를 사용하지 않도록 있습니다 <
, 그리고 >
자바 기능 내장, (같은 substring
, indexOf
, charAt
,과 startsWith
), 아니 정규식, 또는 API의.
나는 이것에 대해 약간의 숙제를했고 코드는 아래에 나와 있지만 정수 유형에서만 작동합니다. 그러나 그들은 작동하는 일반 코드를 작성하라고 float
, double
하고 long
.
// This might not be better way!!
S.O.P ((( number >> 31 ) & 1) == 1 ? "- ve number " : "+ve number );
당신 편에서 어떤 아이디어라도?
정수 케이스는 쉽습니다. 무한에 대해 기억할 때까지 이중 사례는 더 까다 롭습니다.
참고 : 이중 상수 "api의 일부"를 고려하는 경우이를과 같은 오버플로 식으로 대체 할 수 있습니다 1E308 * 2
.
int sign(int i) {
if (i == 0) return 0;
if (i >> 31 != 0) return -1;
return +1;
}
int sign(long i) {
if (i == 0) return 0;
if (i >> 63 != 0) return -1;
return +1;
}
int sign(double f) {
if (f != f) throw new IllegalArgumentException("NaN");
if (f == 0) return 0;
f *= Double.POSITIVE_INFINITY;
if (f == Double.POSITIVE_INFINITY) return +1;
if (f == Double.NEGATIVE_INFINITY) return -1;
//this should never be reached, but I've been wrong before...
throw new IllegalArgumentException("Unfathomed double");
}
다음은 어떤 직업에서든 해고 될 수있는 끔찍한 접근 방식입니다 ...
Stack Overflow Exception [또는 Java가 호출하는 모든 항목]이 발생하는 경우에 따라 달라집니다. 그리고 미친 듯이 0에서 벗어나지 않는 양수에 대해서만 작동합니다.
음수는 괜찮습니다. 양수로 오버플로 한 다음 결국 스택 오버플로 예외가 발생하므로 [거짓 또는 "예, 음수입니다"를 반환합니다.]
Boolean isPositive<T>(T a)
{
if(a == 0) return true;
else
{
try
{
return isPositive(a-1);
}catch(StackOverflowException e)
{
return false; //It went way down there and eventually went kaboom
}
}
}
[0..2]를 제외한 모든 항목에서만 작동합니다.
boolean isPositive = (n % (n - 1)) * n == n;
이와 같은 더 나은 솔루션을 만들 수 있습니다 ([0..1]을 제외하고 작동 함).
boolean isPositive = ((n % (n - 0.5)) * n) / 0.5 == n;
0.5 부분을 2 ^ m (m 정수)와 같이 변경하면 더 나은 정밀도를 얻을 수 있습니다.
boolean isPositive = ((n % (n - 0.03125)) * n) / 0.03125 == n;
다음과 같이 할 수 있습니다.
((long) (num * 1E308 * 1E308) >> 63) == 0 ? "+ve" : "-ve"
여기서 주된 아이디어는 long으로 캐스팅하고 최상위 비트의 값을 확인하는 것입니다. -1과 0 사이의 double / float는 long으로 캐스트 될 때 0으로 반올림되므로 큰 double을 곱하여 음의 float / double이 -1보다 작아집니다. 비정규 가 존재하기 때문에 두 번의 곱셈이 필요합니다 (그렇게 클 필요는 없습니다).
이건 어때?
return ((num + "").charAt(0) == '-');
// Returns 0 if positive, nonzero if negative
public long sign(long value) {
return value & 0x8000000000000000L;
}
다음과 같이 전화하십시오.
long val1 = ...;
double val2 = ...;
float val3 = ...;
int val4 = ...;
sign((long) valN);
double / float / integer에서 long으로 변환하면 실제 값이 아니라면 부호를 유지해야합니다.
당신은 말한다
조건부 연산자를 사용해서는 안됩니다.
그러나 이것은 ==
조건부 연산자 이기 때문에 트릭 요구 사항 입니다. 또한 내장 한이 ? :
, while
그리고 for
루프. 따라서 거의 모든 사람들이 모든 요구 사항을 충족하는 답변을 제공하지 못했습니다.
조건 연산자없이 솔루션을 빌드하는 유일한 방법은 조건이 충족되기 전에 0/1 또는 문자로 요약 될 수있는 몇 가지 다른 사람들의 솔루션 중 하나와 비교표를 사용하는 것입니다.
다음은 룩업 테이블과 비교하여 작동 할 것이라고 생각하는 답변입니다.
- Nabb
- 스티븐 슐 랜스 커
- 데니스 청
- 게리 로우
이 솔루션은 모듈러스를 사용합니다. 그리고 예, 그것은 또한 작동합니다 0.5
(테스트는 아래, 주요 방법).
public class Num {
public static int sign(long x) {
if (x == 0L || x == 1L) return (int) x;
return x == Long.MIN_VALUE || x % (x - 1L) == x ? -1 : 1;
}
public static int sign(double x) {
if (x != x) throw new IllegalArgumentException("NaN");
if (x == 0.d || x == 1.d) return (int) x;
if (x == Double.POSITIVE_INFINITY) return 1;
if (x == Double.NEGATIVE_INFINITY) return -1;
return x % (x - 1.d) == x ? -1 : 1;
}
public static int sign(int x) {
return Num.sign((long)x);
}
public static int sign(float x) {
return Num.sign((double)x);
}
public static void main(String args[]) {
System.out.println(Num.sign(Integer.MAX_VALUE)); // 1
System.out.println(Num.sign(1)); // 1
System.out.println(Num.sign(0)); // 0
System.out.println(Num.sign(-1)); // -1
System.out.println(Num.sign(Integer.MIN_VALUE)); // -1
System.out.println(Num.sign(Long.MAX_VALUE)); // 1
System.out.println(Num.sign(1L)); // 1
System.out.println(Num.sign(0L)); // 0
System.out.println(Num.sign(-1L)); // -1
System.out.println(Num.sign(Long.MIN_VALUE)); // -1
System.out.println(Num.sign(Double.POSITIVE_INFINITY)); // 1
System.out.println(Num.sign(Double.MAX_VALUE)); // 1
System.out.println(Num.sign(0.5d)); // 1
System.out.println(Num.sign(0.d)); // 0
System.out.println(Num.sign(-0.5d)); // -1
System.out.println(Num.sign(Double.MIN_VALUE)); // -1
System.out.println(Num.sign(Double.NEGATIVE_INFINITY)); // -1
System.out.println(Num.sign(Float.POSITIVE_INFINITY)); // 1
System.out.println(Num.sign(Float.MAX_VALUE)); // 1
System.out.println(Num.sign(0.5f)); // 1
System.out.println(Num.sign(0.f)); // 0
System.out.println(Num.sign(-0.5f)); // -1
System.out.println(Num.sign(Float.MIN_VALUE)); // -1
System.out.println(Num.sign(Float.NEGATIVE_INFINITY)); // -1
System.out.println(Num.sign(Float.NaN)); // Throws an exception
}
}
이 코드는 모든 경우와 유형을 다룹니다.
public static boolean isNegative(Number number) {
return (Double.doubleToLongBits(number.doubleValue()) & Long.MIN_VALUE) == Long.MIN_VALUE;
}
이 방법은 래퍼 클래스 (의 수락 Integer
, Long
, Float
및 Double
자동 권투 원시 숫자 유형을 (를) 감사를 int
, long
, float
그리고 double
이 모든 종류의 부호 비트 인 하이 비트, 설정) 간단하게 확인합니다.
다음 true
중 하나를 전달하면 반환 됩니다.
- 모든 부정적인
int
/Integer
- 모든 부정적인
long
/Long
- 모든 부정적인
float
/Float
- 모든 부정적인
double
/Double
Double.NEGATIVE_INFINITY
Float.NEGATIVE_INFINITY
그리고 false
그렇지 않으면.
테스트되지 않았지만 내 아이디어를 보여줍니다.
boolean IsNegative<T>(T v) {
return (v & ((T)-1));
}
나는 당신이 어떤 유형으로 번호를 얻을 수 있는지 모르기 때문에 나에게 임의적 인 것처럼 보이지만 Abs (number)! = number를 확인하는 것은 어떻습니까? 어쩌면 && 숫자! = 0
정수는 사소합니다. 이것은 이미 알고 있습니다. 깊은 문제는 부동 소수점 값을 처리하는 방법입니다. 그 시점에서 부동 소수점 값이 실제로 작동하는 방식에 대해 조금 더 알아야합니다.
키는 Double.doubleToLongBits () 이며 숫자의 IEEE 표현을 얻을 수 있습니다. (이 방법은 NaN 값을 다루는 약간의 마법과 함께 실제로 직접 캐스트입니다.) double이 long으로 변환되면 0x8000000000000000L을 마스크로 사용하여 부호 비트를 선택할 수 있습니다. 0이면 값은 양수이고 1이면 음수입니다.
유효한 답변 인 경우
boolean IsNegative(char[] v) throws NullPointerException, ArrayIndexOutOfBoundException
{
return v[0]=='-';
}
내가 생각할 수있는 또 하나의 옵션
private static boolean isPositive(Object numberObject) {
Long number = Long.valueOf(numberObject.toString());
return Math.sqrt((number * number)) != number;
}
private static boolean isPositive(Object numberObject) {
Long number = Long.valueOf(numberObject.toString());
long signedLeftShifteredNumber = number << 1; // Signed left shift
long unsignedRightShifterNumber = signedLeftShifteredNumber >>> 1; // Unsigned right shift
return unsignedRightShifterNumber == number;
}
이것은 대략 ItzWarty의 답변을 기반으로하지만 로그온 시간에 실행됩니다! 주의 사항 : 정수에서만 작동합니다.
Boolean isPositive(int a)
{
if(a == -1) return false;
if(a == 0) return false;
if(a == 1) return true;
return isPositive(a/2);
}
매우 간단한 해결책이 있다고 생각합니다.
public boolean isPositive(int|float|double|long i){
return (((i-i)==0)? true : false);
}
내가 틀렸다면 말해줘!
코드없이 이것을 시도하십시오. (x-SQRT(x^2))/(2*x)
조건문을 사용하여 작성한 다음 생성 된 어셈블리 코드를 살펴보십시오.
왜 숫자의 제곱근을 구하지 않습니까? 음수 인 경우-java는 오류를 발생시키고 처리합니다.
try {
d = Math.sqrt(THE_NUMBER);
}
catch ( ArithmeticException e ) {
console.putln("Number is negative.");
}
Java가 숫자 값을 정확히 어떻게 강제하는지는 모르겠지만 의사 코드를 입력하면 대답은 매우 간단합니다 (자세한 내용은 귀하에게 맡깁니다).
sign(x) := (x == 0) ? 0 : (x/x)
경우처럼 "=="를 사용할 수있는 경우 배열 인덱스가 범위를 벗어난 경우 예외가 발생한다는 사실을 이용하여 이와 같은 작업을 수행 할 수 있습니다. 코드는 double 용이지만 모든 숫자 유형을 double로 캐스트 할 수 있습니다 (여기서는 최종 정밀도 손실은 전혀 중요하지 않습니다).
프로세스 (값을] -2.0; -1.0] union [1.0; 2.0 [)과 작은 테스트 드라이버로 설명하기 위해 주석을 추가했습니다.
class T {
public static boolean positive(double f)
{
final boolean pos0[] = {true};
final boolean posn[] = {false, true};
if (f == 0.0)
return true;
while (true) {
// If f is in ]-1.0; 1.0[, multiply it by 2 and restart.
try {
if (pos0[(int) f]) {
f *= 2.0;
continue;
}
} catch (Exception e) {
}
// If f is in ]-2.0; -1.0] U [1.0; 2.0[, return the proper answer.
try {
return posn[(int) ((f+1.5)/2)];
} catch (Exception e) {
}
// f is outside ]-2.0; 2.0[, divide by 2 and restart.
f /= 2.0;
}
}
static void check(double f)
{
System.out.println(f + " -> " + positive(f));
}
public static void main(String args[])
{
for (double i = -10.0; i <= 10.0; i++)
check(i);
check(-1e24);
check(-1e-24);
check(1e-24);
check(1e24);
}
출력은 다음과 같습니다.
-10.0 -> false
-9.0 -> false
-8.0 -> false
-7.0 -> false
-6.0 -> false
-5.0 -> false
-4.0 -> false
-3.0 -> false
-2.0 -> false
-1.0 -> false
0.0 -> true
1.0 -> true
2.0 -> true
3.0 -> true
4.0 -> true
5.0 -> true
6.0 -> true
7.0 -> true
8.0 -> true
9.0 -> true
10.0 -> true
-1.0E24 -> false
-1.0E-24 -> false
1.0E-24 -> true
1.0E24 -> true
비효율적이지만 여기서는 중요하지 않다고 생각합니다. (저는 또한 Java에 대해 약간 녹슬 었습니다. 이것이 다소 정확한 구문이기를 바랍니다.)
boolean isPositive = false;
int n = (int)(x * x);
while (n-- != 0)
{
if ((int)(--x) == 0)
{
isPositive = true;
break;
}
}
이것은 x
대부분의 x * x
경우 (항상 양수) 감소하고 x
0과 같지 않으면 음수 여야 시작하기 때문에 작동합니다. 경우 x
, 다른 한편으로는, 어떤 점에서 0 일, 그것은에 postive되어 있어야합니다.
이 발생할 것이라고 참고 isPositive
인 false
0.
추신 : 분명히, 이것은 (int)(x * x)
오버플로 될 것이기 때문에 매우 큰 숫자에서는 작동하지 않습니다 .
음, 캐스팅을 활용하면 (실제 값이 무엇인지 신경 쓰지 않기 때문에) 아마도 다음과 같은 것이 효과가있을 것입니다. 실제 구현은 API 규칙을 위반하지 않습니다. 나는 {-1, + 1} 문제 도메인에 대한 @chris의 코멘트에 비추어 메서드 이름을 좀 더 분명하게 만들기 위해 이것을 편집했습니다. 본질적으로이 문제는 float 및 double 프리미티브의 기본 비트 구조를 참조하는 Float 또는 Double 내의 API 메서드에 의존하지 않고는 해결할 수없는 것으로 보입니다.
다른 사람들이 말했듯이 : 어리석은 인터뷰 질문. Grr.
public class SignDemo {
public static boolean isNegative(byte x) {
return (( x >> 7 ) & 1) == 1;
}
public static boolean isNegative(short x) {
return (( x >> 15 ) & 1) == 1;
}
public static boolean isNegative(int x) {
return (( x >> 31 ) & 1) == 1;
}
public static boolean isNegative(long x) {
return (( x >> 63 ) & 1) == 1;
}
public static boolean isNegative(float x) {
return isNegative((int)x);
}
public static boolean isNegative(double x) {
return isNegative((long)x);
}
public static void main(String[] args) {
// byte
System.out.printf("Byte %b%n",isNegative((byte)1));
System.out.printf("Byte %b%n",isNegative((byte)-1));
// short
System.out.printf("Short %b%n",isNegative((short)1));
System.out.printf("Short %b%n",isNegative((short)-1));
// int
System.out.printf("Int %b%n",isNegative(1));
System.out.printf("Int %b%n",isNegative(-1));
// long
System.out.printf("Long %b%n",isNegative(1L));
System.out.printf("Long %b%n",isNegative(-1L));
// float
System.out.printf("Float %b%n",isNegative(Float.MAX_VALUE));
System.out.printf("Float %b%n",isNegative(Float.NEGATIVE_INFINITY));
// double
System.out.printf("Double %b%n",isNegative(Double.MAX_VALUE));
System.out.printf("Double %b%n",isNegative(Double.NEGATIVE_INFINITY));
// interesting cases
// This will fail because we can't get to the float bits without an API and
// casting will round to zero
System.out.printf("{-1,1} (fail) %b%n",isNegative(-0.5f));
}
}
이 솔루션은 조건부 연산자를 사용하지 않지만 두 가지 예외를 포착하는 데 의존합니다.
나누기 오류는 원래 "음수"인 숫자와 동일합니다. 또는 숫자가 결국 행성에서 떨어지고 양수인 경우 StackOverFlow 예외가 발생합니다.
public static boolean isPositive( f)
{
int x;
try {
x = 1/((int)f + 1);
return isPositive(x+1);
} catch (StackOverFlow Error e) {
return true;
} catch (Zero Division Error e) {
return false;
}
}
What about the following?
T sign(T x) {
if(x==0) return 0;
return x/Math.abs(x);
}
Should work for every type T...
Alternatively, one can define abs(x) as Math.sqrt(x*x), and if that is also cheating, implement your own square root function...
if (((Double)calcYourDouble()).toString().contains("-"))
doThis();
else doThat();
Combined generics with double API. Guess it's a bit of cheating, but at least we need to write only one method:
static <T extends Number> boolean isNegative(T number)
{
return ((number.doubleValue() * Double.POSITIVE_INFINITY) == Double.NEGATIVE_INFINITY);
}
Two simple solutions. Works also for infinities and numbers -1 <= r <= 1 Will return "positive" for NaNs.
String positiveOrNegative(double number){
return (((int)(number/0.0))>>31 == 0)? "positive" : "negative";
}
String positiveOrNegative(double number){
return (number==0 || ((int)(number-1.0))>>31==0)? "positive" : "negative";
}
There is a function is the math library called signnum.
http://www.tutorialspoint.com/java/lang/math_signum_float.htm http://www.tutorialspoint.com/java/lang/math_signum_double.htm
It's easy to do this like
private static boolean isNeg(T l) {
return (Math.abs(l-1)>Math.abs(l));
}
ReferenceURL : https://stackoverflow.com/questions/3994531/how-to-determine-if-a-number-is-positive-or-negative
'programing' 카테고리의 다른 글
std :: max 호출 문제 (0) | 2020.12.27 |
---|---|
선택적 인수로 데코레이터 만들기 (0) | 2020.12.27 |
Git에서 풀 요청을 보내는 방법 (0) | 2020.12.27 |
LaTex에서 첫 번째 섹션이 발생하는 페이지 번호를 어떻게 시작할 수 있습니까? (0) | 2020.12.27 |
사용자가 파일을 선택할 때 파일 이름을 얻는 방법 (0) | 2020.12.27 |