“Длинный x = 1/2” равный 1 или 0, и почему? [дубликат]

8
задан mjv 3 February 2010 в 01:33
поделиться

5 ответов

- 3723771-

Если это COM DLL, все, что вам нужно сделать, это добавить его в качестве ссылки на ваш проект, а затем вы можете вызвать функции, которые находятся в DLL.

Да, вы можете использовать функции низкого уровня, такие как DllgetClassObject, но зачем вам?

-121--3763394-

Это делает целочисленное разделение, которое обрезает все справа от десятичной точки.

29
ответ дан 5 December 2019 в 04:37
поделиться

Вот небольшой код, показывающий, как получить фабрику классов и использовать ее для создания COM-объекта. Он использует структуру, чтобы сохранить трека дескриптора модуля и указателя функции Dll GetClassObject. Вы должны держаться за дескриптор модуля, пока не закончите работу с COM-объектом.

Для использования этой функции необходимо выделить экземпляр структуры ComModureInfo и задать имя файла DLL или полный путь к файлу szDLL. Затем вызовите функцию с идентификатором класса и идентификатором интерфейса COM-объекта, который требуется получить из этой DLL.

typedef struct {
   TCHAR   szDLL[MAX_PATH];
   HMODULE hModule;
   HRESULT (WINAPI *pfnGetFactory)(REFCLSID, REFIID, void**);
   } ComModuleInfo;

HRESULT CreateCOMObject(
   ComModuleInfo & mod,  // [in,out] 
   REFCLSID iidClass,    // [in] CLSID of the COM object to create
   REFIID iidInterface,  // [in] GUID of the interface to get
   LPVOID FAR* ppIface)  // [in] on success, interface to the COM object is returned
{
    HRESULT hr = S_OK;

    *ppIface = NULL; // in case we fail, make sure we return a null interface.

    // init the ComModuleInfo if this is the first time we have seen it.
    //
    if ( ! mod.pfnGetFactory)
    {     
       if ( ! mod.hModule)
       {
          mod.hModule = LoadLibrary(mod.szDLL);
          if ( ! mod.hModule)
             return HRESULT_FROM_WIN32(GetLastError());
       }
       mod.pfnGetFactory = (HRESULT (WINAPI *)(REFCLSID, REFIID, void**))GetProcAddress(mod.hModule, "DllGetClassObject");
       if ( ! mod.pfnGetFactory)
          return HRESULT_FROM_WIN32(GetLastError());
    }

    IClassFactory* pFactory = NULL;
    hr = mod.pfnGetFactory(iidClass, IID_IClassFactory, (void**)&pFactory);
    if (SUCCEEDED(hr))
    {
       hr = pFactory->CreateInstance(NULL, iidInterface, (void**)ppIface);
       pFactory->Release();
    }

    return hr;
}
-121--3763393-

Руководство по базовому вводу/выводу содержит подробную информацию.

-121--5044534-

Целочисленное деление имеет корни в теории чисел. Когда вы делаете 1/2 вы спрашиваете, сколько раз 2 равно 1? Ответ никогда, поэтому уравнение становится 0 * 2 + 1 = 1, где 0 - частное (то, что вы получаете от 1/2), а 1 - остаток (то, что вы получаете от 1% 2).

Правильно указать, что% не является истинным модулем в математическом смысле, но всегда остаток от деления. Есть разница, когда вы имеете дело с отрицательными целыми числами.

Надеюсь, что это поможет.

6
ответ дан 5 December 2019 в 04:37
поделиться

, что делает это выражение, это сначала объявляет существование длительного называемого X, а затем присвоение ему значения права выражение стороны руки. Правая сторона стороны составляет 1/2, а с 1 и 2 - это оба целых числа, это интерпретируется как целое отделение. С целочисленным делением результат всегда является целым числом, поэтому что-то вдоль линии 5/3 вернутся 1, как только один три подходящих в пятерку. Так что с 1/2, сколько 2s может вписаться в 1? 0.

Это может на некоторых языках привести к некоторым интересным выходам, если вы пишете что-то вроде двойной х = 1/2. Вы можете ожидать 0,5 в этом случае, но он часто будет оценивать целочисленное значение вправо сначала до назначения и преобразования результата в двойную, придавая значение 0.0

Важно отметить, что при выполнении этого типа преобразования типа Это никогда не приведет к результату. Так что, если вы сделаете наоборот: длинный х = (длинный) (1,0 / 2.0); Тогда в то время как (1.0 / 2.0) будет оценивать до 0,5, (длинный) отброс принудит это, чтобы быть усеченным до 0. Даже если у меня длинный x = (длинный) (0,9), результат все равно будет 0. Он просто усечен после десятичной точки.

5
ответ дан 5 December 2019 в 04:37
поделиться

Существует множество различных конвенций округления, наиболее распространенное округление к + инф, округление к -инфу и округление к нулю. Многие люди предполагают, что есть один правильный путь, но все они имеют разные идеи о том, что должно быть, что в один из способов; -)

Нет промежуточного не целочисленного результата для целочисленного подразделения, но, конечно, раздел делается детерминистически, и Одной из конкретной конвенции о округрении всегда будет следовать для определенной платформы и компилятора.

С Visual C ++ я получаю 5/2 = 2 и -5/2 = -2, округление к нулю.

Округление в C, C ++ и Java обычно называют «усечением» - значение выпадайте от нежелательных битов. Но это может ввести в заблуждение . Используя 4-битный 2S дополнить двоичный двоичный, выполняющий то, что подразумевает усечение ...

 5/2 = 0101/0010 = 0010.1 --> 0010 =  2
-5/2 = 1011/0010 = 1101.1 --> 1101 = -3

, который округляется в направлении -infinity, который является то, что делает Python (или, по крайней мере, что он сделал в Python 2.5).

Усечение было бы правильным словом, если мы использовали представление о значении знака, но комплемент TWOS был стандартом де-факто на протяжении десятилетий.

В C и C ++ я ожидаю, что он обычно называется усечением, в действительности эта деталь не определена в стандартах и ​​оставлена ​​в результате реализации - оправдание для того, чтобы компилятор использовать самый простой и самый быстрый метод для платформы (что Инструкция по разделению процессоров естественно делает). Это только проблема, если у вас есть отрицательные числа, хотя - я еще не видел любой язык или реализацию, который даст 5/2 = 3.

Я не знаю, что говорит стандарт Java. Руководство Python определяет разделение «напольное», которое является общим термином для округления до -infinity.

Редактировать

дополнительную ноту - по определению, если A / B = C остаток D, то A = (B * C) + d. Для этого, чтобы удержать, вы должны выбрать остаток, чтобы набрать вашу конвенцию о округрении.

Люди, как правило, предполагают, что остатки и модулы одинаковы, но подписанные значения, они могут быть разными - в зависимости от правил округления. Значения модуля по определению никогда не отрицательны, но остатки могут быть отрицательными.

Я подозреваю, что правило для негативного бесконечности Python призвано обеспечить, чтобы один оператор% был действителен как в течение остатка, так и в качестве модуля. В C и C ++, какие% означает (остаток или модуль) (да, вы уже догадались).

ADA на самом деле имеет два отдельных оператора - мод и REM. С дивизией, необходимым для раунда к нулю, так что мод и REM делают , дают разные результаты.

1
ответ дан 5 December 2019 в 04:37
поделиться

Оно не может округляться, потому что оно никогда не может быть округлено

Выражение «1/2» никогда не было 0,5 до присвоения long

Теперь long x = 1,0 / 2,0 , потому что выражение справа перед assign допустимо для округления. Если вы не получите 0,499999999999997 ...

4
ответ дан 5 December 2019 в 04:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: