Resta sin signo menos

¿Cómo puedo restar dos enteros en C sin el operador - ?

 int a = 34; int b = 50; 

Puedes convertir b a un valor negativo usando la negación y agregando 1:

 int c = a + (~b + 1); printf("%d\n", c); -16 

Esta es la negación de signo de complemento de dos. El procesador lo está haciendo cuando usa el operador ‘-‘ cuando quiere negar un valor o subestralizarlo.

Convertir el flotador es más sencillo. Solo niega el primer bit (shoosh te dio un ejemplo de cómo hacer esto).

EDITAR:

Ok muchachos. Me doy por vencido. Aquí está mi versión independiente del comstackdor:

 #include  unsigned int adder(unsigned int a, unsigned int b) { unsigned int loop = 1; unsigned int sum = 0; unsigned int ai, bi, ci; while (loop) { ai = a & loop; bi = b & loop; ci = sum & loop; sum = sum ^ ai ^ bi; // add i-th bit of a and b, and add carry bit stored in sum i-th bit loop = loop << 1; if ((ai&bi)|(ci&ai)|(ci&bi)) sum = sum^loop; // add carry bit } return sum; } unsigned int sub(unsigned int a, unsigned int b) { return adder(a, adder(~b, 1)); // add negation + 1 (two's complement here) } int main() { unsigned int a = 35; unsigned int b = 40; printf("%u - %u = %d\n", a, b, sub(a, b)); // printf function isn't compiler independent here return 0; } 

Estoy usando unsigned int para que cualquier comstackdor lo trate igual.

Si quieres restar valores negativos, hazlo de esa manera:

  unsgined int negative15 = adder(~15, 1); 

Ahora somos completamente independientes de los convenios de valores firmados. En mi enfoque de resultado, todas las entradas se almacenarán como complemento de dos, por lo que debe tener cuidado con las entradas más grandes (tienen que comenzar con 0 bits).

Pontus tiene razón, el complemento de 2 no está obligado por el estándar C (incluso si es el estándar de hardware de facto). +1 para las respuestas creativas de Phil; Aquí hay otro enfoque para obtener -1 sin usar la biblioteca estándar o el operador -.

C exige tres representaciones posibles, para que pueda detectar lo que está en funcionamiento y obtener un -1 diferente para cada una:

 negation= ~1; if (negation+1==0) /* one's complement arithmetic */ minusone= ~1; else if (negation+2==0) /* two's complement arithmetic */ minusone= ~0; else /* sign-and-magnitude arithmetic */ minusone= ~0x7FFFFFFE; r= a+b*minusone; 

El valor 0x7FFFFFFFE dependería del ancho (número de ‘bits de valor’) del tipo de entero en el que estaba interesado; Si no se especifica, tienes más trabajo para descubrirlo.

  • + Sin ajuste de bits
  • + Idioma independiente
  • + Se puede ajustar para diferentes tipos de números (int, float, etc.)
  • – Es casi seguro que no es la respuesta de tu tarea C (que probablemente sea sobre bits)

Expandir ab:

 ab = a + (-b)
     = a + (-1) .b

Fabricación -1:

 flotar: pi = asin (1.0);
 (con minusone_flt = sin (3.0 / 2.0 * pi);
 math.h) o = cos (pi)
                   o = log10 (0.1)
 complejo: minusone_cpx = (0,1) ** 2;  // yo cuadré
 entero: minusone_int = 0;  minusone_int--;  // o convertir uno de los flotadores arriba

Dado que la encoding de enteros para admitir el complemento de dos no es obligatoria en C, iterar hasta que se haga. Si quieren que saltes a través de aros en llamas, ¡no hay necesidad de ser eficiente al respecto!

 int subtract(int a, int b) { if ( b < 0 ) return a+abs(b); while (b-- > 0) --a; return a; } 

Pregunta tonta … probablemente entrevista tonta!

Si desea hacerlo para flotadores, comience desde un número positivo y cambie su signo ligeramente así:

 float f = 3; *(int*)&f |= 0x80000000; // now f is -3. float m = 4 + f; // m = 1 

También puede hacer esto para los dobles utilizando el entero apropiado de 64 bits. en visual studio esto es __int64 por ejemplo.

  • + Sin ajuste de bits
  • + Idioma independiente
  • + Independiente del tipo de número (int, float, etc.)
  • Requiere a> b (es decir, resultado positivo)
  • – Es casi seguro que no es la respuesta de tu tarea de C (que probablemente sea sobre bits)
  •   a - b = c 

    restringiéndonos al espacio numérico 0 <= c <(a + b):

            (a - b) mod (a + b) = c mod (a + b)
     a mod (a + b) - b mod (a + b) = c mod (a + b)
    

    simplificando el segundo término:

     (-b) .mod (a + b) = (a + bb) .mod (a + b)
                   = a.mod (a + b)
    

    sustituyendo

     a.mod (a + b) + a.mod (a + b) = c.mod (a + b)
     2 a.mod (a + b) = c.mod (a + b)
    

    si b> a, entonces ba> 0, entonces:

     c.mod (a + b) = c
     c = 2 a.mod (a + b)
    

    Entonces, si a es siempre mayor que b, entonces esto funcionaría.

    Eche un vistazo aquí: Agregar / Restar usando operadores bitwise

    Supongo que esto

    b – a = ~ (a + ~ b)

    Estilo de assembly (acumulador):

     int result = a; result -= b; 

    Para restar en C dos enteros solo necesitas:

     int subtract(int a, int b) { return a + (~b) + 1; } 

    No creo que haya una solución simple y elegante para números flotantes o dobles como para enteros. Para que pueda transformar sus números flotantes en matrices y aplicar un algoritmo similar con uno simulado aquí

    Como la pregunta formulada para enteros no int s, puede implementar un intérprete pequeño que use números de la Iglesia .

    ¡Cree una tabla de búsqueda para cada posible caso de int-int!

    No probado. Sin usar el complemento de 2:

     #include  #include  int sillyNegate(int x) { if (x <= 0) return abs(x); else { // setlocale(LC_ALL, "C"); // if necessary. char buffer[256]; snprintf(buffer, 255, "%c%d", 0x2d, x); sscanf(buffer, "%d", &x); return x; } } 

    Suponiendo que la longitud de un int es mucho menor que 255, y el viaje de ida y vuelta snprintf / sscanf no producirá ningún comportamiento no especificado (¿verdad? ¿Correcto?).

    La resta se puede calcular utilizando a - b == a + (-b).


    Alternativa:

     #include  int moreSillyNegate(int x) { return x * ilogb(0.5); // ilogb(0.5) == -1; } 

    Esto funcionaría usando un desbordamiento de enteros:

     #include int subtractWithoutMinusSign(int a, int b){ return a + (b * (INT_MAX + INT_MAX + 1)); } 

    Esto también funciona para flotadores (asumiendo que haces una versión flotante …)

    Para el rango máximo de cualquier tipo de datos, el complemento negativo proporciona el valor negativo disminuido en 1 a cualquier valor correspondiente. ex:
    ~ 1 ——–> -2
    ~ 2 ———> -3
    y así sucesivamente … Te mostraré esta observación usando un pequeño fragmento de código

     #include int main() { int a , b; a=10; b=~a; // b-----> -11 printf("%d\n",a+~b+1);// equivalent to ab return 0; } 

    Salida: 0
    Nota: Esto es válido solo para el rango de tipo de datos. medios para el tipo de datos int esta regla solo será aplicable para el valor del rango [-2,147,483,648 a 2,147,483,647]. Gracias ….. Que esto te ayude

      int num1, num2, count = 0; Console.WriteLine("Enter two numebrs"); num1 = int.Parse(Console.ReadLine()); num2 = int.Parse(Console.ReadLine()); if (num1 < num2) { num1 = num1 + num2; num2 = num1 - num2; num1 = num1 - num2; } for (; num2 < num1; num2++) { count++; } Console.WriteLine("The diferrence is " + count); 
     void main() { int a=5; int b=7; while(b--)a--; printf("sud=%d",a); }