سؤال

----------محدث ------------

كان Codymanix و Moonshadow مساعدة كبيرة حتى الآن. تمكنت من حل مشكلتي باستخدام المعادلات وبدلاً من استخدام التحول الصحيح الذي أقسمه على 29. لأنه مع توقيع 32Bits 2^31 = الفائض إلى 29. الذي يعمل!

النموذج الأولي في PHP

$r = $x - (($x - $y) & (($x - $y) / (29)));

الكود الفعلي للعروض (يمكنك فقط القيام بوظيفة رياضية واحدة لكل سطر !!! ahhhh !!!)

DERIVDE1 = IMAGE1 - IMAGE2;
DERIVED2 = DERIVED1 / 29;
DERIVED3 = DERIVED1 AND DERIVED2;
MAX = IMAGE1 - DERIVED3;

---------- السؤال الأصلي -----------
لا أعتقد أن هذا ممكن تمامًا من خلال حدود طلبي ، لكنني اعتقدت أن الأمر يستحق أن يسأل.

سأحاول جعل هذا بسيطًا. أحتاج إلى العثور على القيم الأقصى بين رقمين دون أن أتمكن من استخدام IF أو أي عبارة مشروطة.

من أجل العثور على قيم Max التي لا يمكنني تنفيذ الوظائف التالية إلا

Divide, Multiply, Subtract, Add, NOT, AND ,OR

دعنا نقول أن لدي رقمين

A = 60;
B = 50;

الآن إذا كان A دائمًا أكبر من B ، فسيكون من السهل العثور على قيمة الحد الأقصى

MAX = (A - B) + B;
ex. 
10 = (60 - 50)
10 + 50 = 60 = MAX

المشكلة ليست دائمًا أكبر من ب.

هل هناك أي طريقة ممكنة باستخدام العملية المحدودة أعلاه للعثور على قيمة قريبة جدًا من الحد الأقصى؟

هل كانت مفيدة؟

المحلول

إيجاد الحد الأقصى للمتغيرات 2:

max = a-((a-b)&((a-b)>>31))

حيث >> هو bitwise right-shift (يسمى أيضًا shr أو asr depeding على التوقيع).

بدلاً من 31 ، يمكنك استخدام عدد البتات التي تحتوي على أرقامك ناقص واحد.

نصائح أخرى

أعتقد أن هذا سيكون أبسط إذا تمكنا من إيجاد فرق بين رقمين (فقط لا يوقع الحجم)

max = ((a+b)+|a-b|)/2;

أين |a-b| هو حجم الفرق بين a و b.

إذا لم تتمكن من الوثوق ببيئتك لإنشاء العمليات المناسبة بدون فرع عند توفرها ، انظر هذه الصفحة لكيفية المتابعة. لاحظ التقييد على نطاق الإدخال ؛ استخدم نوعًا صحيحًا أكبر للعملية إذا لم تتمكن من ضمان ملائمة المدخلات الخاصة بك.

الحل بدون شرطية. يلقي إلى Uint ثم العودة إلى int للحصول على القيمة المطلقة.

int abs (a) { return (int)((unsigned int)a); }
int max (a, b) { return (a + b + abs(a - b)) / 2; }

int max3 (a, b, c) { return (max(max(a,b),c); }

باستخدام العمليات المنطقية فقط ، تقييم الدائرة القصيرة وافتراض اتفاقية C للالتقاء نحو الصفر ، من الممكن التعبير عن ذلك على النحو التالي:

int lt0(int x) {
    return x && (!!((x-1)/x));
}

int mymax(int a, int b) {
    return lt0(a-b)*b+lt0(b-a)*a;
}

الفكرة الأساسية هي تنفيذ مشغل مقارنة سيعود 0 أو 1. من الممكن القيام بخدعة مماثلة إذا كانت لغة البرمجة النصية الخاصة بك تتبع اتفاقية التقريب نحو قيمة الأرضية كما تفعل Python.

أمم. أنا لا أفترض ، و ، أو هي bitwise؟ إذا كان الأمر كذلك ، فسيكون هناك تعبير قليلاً لحل هذا. لاحظ أن | سيقدم B رقمًا> = A و> = B. ربما هناك طريقة تقليم لتحديد الرقم مع معظم البتات.

لتمديد ، نحتاج إلى ما يلي لتحديد ما إذا كان A (0) أو B (1) أكبر.

جدول الحقيقة:

0|0 = 0  
0|1 = 1
1|0 = 0
1|1 = 0

!A and B

لذلك ، سوف يعطي فهرس البت الأكبر. ergo ، قارن كل بت في كلا الرقمين ، وعندما يختلفون ، استخدم التعبير أعلاه (وليس A و B) لتحديد الرقم كان أكبر. ابدأ من أهم بت وتواصل كلا البايتات. إذا لم يكن لديك بنية حلقة ، قارن كل بت يدويًا.

تنفيذ "عندما يكونون مختلفون":

(أ! = ب) و (منطقي هنا)

function Min(x,y:integer):integer;
  Var
   d:integer;
   abs:integer;
 begin
  d:=x-y;
  abs:=d*(1-2*((3*d) div (3*d+1)));
  Result:=(x+y-abs) div 2;
 end;

جرب هذا ، (ولكن كن على دراية بالفيضانات) (رمز في C#)

    public static Int32 Maximum(params Int32[] values)
    {
        Int32 retVal = Int32.MinValue;
        foreach (Int32 i in values)
            retVal += (((i - retVal) >> 31) & (i - retVal));
        return retVal;        
    }

يمكنك التعبير عن هذا كسلسلة من العمليات الحسابية والجدوى ، على سبيل المثال:

int myabs(const int& in) {
  const int tmp = in >> ((sizeof(int) * CHAR_BIT) - 1);
  return tmp - (in ^ tmp(;
}

int mymax(int a, int b) {
    return ((a+b) + myabs(b-a)) / 2;
}

يرجى إلقاء نظرة على هذا البرنامج .. قد يكون هذا هو أفضل إجابة حتى الآن في هذه الصفحة ...

#include <stdio.h>

int main()
{
    int a,b;
    a=3;
    b=5;
    printf("%d %d\n",a,b);
    b = (a+b)-(a=b); // this line is doing the reversal
    printf("%d %d\n",a,b);
    return 0;
}
//Assuming 32 bit integers 
int is_diff_positive(int num)
{
    ((num & 0x80000000) >> 31) ^ 1; // if diff positive ret 1 else 0
}
int sign(int x)
{
   return ((num & 0x80000000) >> 31);
}

int flip(int x)
{
   return x ^ 1;
}

int max(int a, int b)
{
  int diff = a - b;

  int is_pos_a = sign(a);
  int is_pos_b = sign(b);

  int is_diff_positive = diff_positive(diff);
  int is_diff_neg = flip(is_diff_positive);

  // diff (a - b) will overflow / underflow if signs are opposite
  // ex: a = INT_MAX , b = -3 then a - b => INT_MAX - (-3) => INT_MAX + 3
  int can_overflow = is_pos_a ^ is_pos_b;
  int cannot_overflow = flip(can_overflow);
  int res = (cannot_overflow * ( (a * is_diff_positive) + (b * 
            is_diff_negative)) + (can_overflow * ( (a * is_pos_a) + (b * 
            is_pos_b)));

  return res;

}

يعتمد ذلك على اللغة التي تستخدمها ، ولكن عامل ثلاثي من الممكن ان يكون مفيدا.

ولكن بعد ذلك ، إذا لم تتمكن من إجراء عمليات فحص مشروطة في "تطبيق البرمجة النصية" ، فربما لا يكون لديك المشغل الثلاثية.

إذا كان A دائمًا أكبر من ب .. [يمكننا استخدام] .. MAX = (A - B) + B;

لا حاجة. فقط استخدم: int maxA(int A, int B){ return A;}

(1) إذا سمح لك الشرطية بذلك max = a>b ? a : b.

(2) أي طريقة أخرى إما تستخدم مجموعة محددة من الأرقام أو الاعتماد على الشيكات الشرطية الضمنية.

(2A) max = a-((a-b)&((a-b)>>31)) هذا أنيق ، لكنه يعمل فقط if يمكنك استخدام أرقام 32 بت. يمكنك توسيع عدد كبير من العدد الكبير ، لكن الطريقة ستفشل إذا حاولت العثور على Max (N-1 ، N+1). تعمل هذه الخوارزمية على Automata المحدودة ، ولكن ليس آلة تورينج.

(2 ب) الحجم |a-b| هو حالة |a-b| = a-b>0 a-b : b-a

ماذا عن:
enter image description here

الجذر التربيعي هو أيضا حالة. كلما c>0 و c^2 = d لدينا الحل الثاني -c, ، لان (-c)^2 = (-1)^2*c^2 = 1*c^2 = d. الجذر التربيعي يعيد أعظم في الزوج. أنا أتي مع بناء في int max(int c1, int c2){return max(c1, c2);}

بدون مقارنة لمشغل المقارنة ، فإن الرياضيات متماثلة للغاية وكذلك محدودة في السلطة. لا يمكن تمييز الأرقام الإيجابية والسلبية بدون if من نوع ما.

#region GetMaximumNumber
/// <summary>
/// Provides method to get maximum values.
/// </summary>
/// <param name="values">Integer array for getting maximum values.</param>
/// <returns>Maximum number from an array.</returns>
private int GetMaximumNumber(params int[] values)
{
  // Declare to store the maximum number.
  int maximumNumber = 0;
  try
  {
    // Check that array is not null and array has an elements.
    if (values != null &&
        values.Length > 0)
    {
      // Sort the array in ascending order for getting maximum value.
      Array.Sort(values);

      // Get the last value from an array which is always maximum.
      maximumNumber = values[values.Length - 1];
    }
  }
  catch (Exception ex)
  {
    throw ex;
  }
  return maximumNumber;
}
#endregion
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top