Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Long Long в MSVC 1.5


Автор: x8m6 22.1.2012, 16:14
Компилю код компилятором Microsoft Visual C++ 1.5. В коде объявлена константа типа long long:
Код

#define BIGINTVALUE     77356848298LL

При компиляции через NMAKE появляется ошибка:
Код

 error C2059: syntax error : 'bad suffix on number'
 error C2177: constant too big
 error C2146: syntax error : missing ')' before identifier 'L'
1>NMAKE : fatal error U1077: 'C:\MSVC15\bin\cl.exe' : return code '0x2'

Автор: Daevaorn 22.1.2012, 16:29
В чем вопрос?

Автор: x8m6 22.1.2012, 16:50
Цитата

В чем вопрос? 

Как решить проблему или как в VC++ 1.5 задать такую константу? 

Автор: borisbn 22.1.2012, 21:12
Есть подозрение, что в 1983-м году студия была 16-битной и в ней просто не было возможности задавать 64-х битные числа.
Выбери студию поновее. У них есть и http://www.microsoft.com/visualstudio/en-us/products/2010-editions/express

Автор: x8m6 22.1.2012, 23:25
borisbn, ты думаешь что я настолько отстал от жизни что пишу на студии 1983 года? Нет. Просто нужно скомпилить одну часть проекта этим компилятором. 

Автор: volatile 23.1.2012, 00:28
x8m6, попробуйте написать так
Код

 #define BIGINTVALUE     77356848298i64

Если не прокатит, то значит там действительно еще нет поддержки 64-разрядных чисел.
Остается в этом случае писать свою библиотеку 64-разрядной арифметики  smile 
Вообще-то это не не так и сложно.. Только зачем?
Ради спортивного итереса?

Автор: Dem_max 23.1.2012, 08:50
Я думаю не поможет

Автор: x8m6 23.1.2012, 14:00
volatile, не помогло.
Хорошо, тогда немного другой вопрос. Как записать 64 битное число двумя 32 битными (low and high части)? Если поможете кодом буду только рад. 

Автор: borisbn 23.1.2012, 14:41
Цитата(x8m6 @  23.1.2012,  14:00 Найти цитируемый пост)
Как записать 64 битное число двумя 32 битными (low and high части)?

Код

#define BIGINTVALUE_LOW 0x42000102
#define BIGINTVALUE_HI  0xBAADFACE
#define BIGINTVALUE ( ( ((unsigned long long)BIGINTVALUE_HI) << 32 ) | BIGINTVALUE_LOW )

Автор: x8m6 23.1.2012, 20:13
Я наверно не правильно вопрос поставил. Как вычислить 32-битные low и high части от 64-битного числа. Т.е. нужна функция:
Код

void to32bit(long long l,int& lo, int& hi){
  // insert code here
}

Автор: volatile 23.1.2012, 23:15
Цитата(x8m6 @  23.1.2012,  20:13 Найти цитируемый пост)
Как вычислить 32-битные low и high части от 64-битного числа. Т.е. нужна функция:
void to32bit(long long l,int& lo, int& hi){
  // insert code here
}

Как-то так:
Код

void to32bit(long long l,int& lo, int& hi){
   lo = (int)l;
   hi = (int)(l >>32);
}



Автор: x8m6 24.1.2012, 10:43
Вот на этом примере почему то не работает:
Код

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <conio.h> 


void to32bit(unsigned long long l,int& lo, int& hi){
   lo = (int)l;
   hi = (int)(l >>32);
}

unsigned long long to64bit(int lo, int hi){
    return ((((unsigned long long)hi) << 32 ) | lo );
}

int _tmain(int argc, _TCHAR* argv[])
{

  unsigned long long big = 11386655755LL;
  int lo,hi;
  to32bit(big,lo,hi);
  unsigned long long l = to64bit(lo,hi);

  std::cout<<"lo="<<lo<<std::endl;
  std::cout<<"hi="<<hi<<std::endl;
  std::cout<<"l="<<l<<std::endl;
   
  getch();
  return 0;
}
}


Если вместо 11386655755 поставить 77356848298 то все нормально вычисляется. В чем дело?

Автор: borisbn 24.1.2012, 10:49
замени везде int на unsigned int и всё будет ОК.
http://liveworkspace.org/code/060f4e9f7f426f6298dd562dc55a5885
Дело в том, что при сдвиге знакового числа заполнение "слева" идёт не нулями, а знаковым битом.
Грубо говоря, в int не 32 значащих бита, а 31 и один - для определения знака числа.
Ты же пытаешься записать в int все 32 бита, и у тебя получается, что 31 записываются как значащие, а один (изначально тоже значащий) - как знак.

Автор: x8m6 24.1.2012, 11:44
Еще очень нужна функция целочисленного деления:
Код

unsigned long long div(unsigned long long num,unsigned int divider)

Автор: borisbn 24.1.2012, 11:49
Цитата(x8m6 @  24.1.2012,  11:44 Найти цитируемый пост)
Еще очень нужна функция целочисленного деления:

res = num / divider; // res - целая часть от деления num на divider при условии, что и num и divider - целые
res = num % divider; // res - остаток от деления num на divider

x8m6, скажи честно, ты хоть одну книгу открыл по Си++ ?

Автор: x8m6 24.1.2012, 12:57
borisbn, мне нужно непростое целочисленное деление как видишь. num нужно разложить на две uint32 части. Их поделить на divider, а потом опять собрать в int64. Как собирать и разбирать я уже знаю. А вот как поделить нет.
Т.е. у меня сомнения по поводу этого кода:
Код

unsigned long long div(unsigned long long num,unsigned int divider){
unsigned int hi,lo;
to32bit(num,lo,hi);
lo = lo/divider;
hi = hi/divider;
return to64bit(lo,hi);
}

Книги открывал, и не одну.   

Автор: borisbn 24.1.2012, 13:13
Цитата(x8m6 @  24.1.2012,  12:57 Найти цитируемый пост)
Т.е. у меня сомнения по поводу этого кода:

не очень понял, зачем всё это нужно, но, судя по описанию, в коде всё правильно, за исключением
Цитата(x8m6 @  24.1.2012,  12:57 Найти цитируемый пост)
int hi,lo;

Д.б. unsigned int. Откажись от знаковых чисел, если тебе в принципе не нужны отрицательные

Автор: x8m6 24.1.2012, 15:51
Все таки как - то по другому надо делить
http://liveworkspace.org/code/63b7e6059aa38de3eb38f413add3a62d

Автор: volatile 25.1.2012, 01:07
Цитата(x8m6 @  24.1.2012,  12:57 Найти цитируемый пост)
Т.е. у меня сомнения по поводу этого кода:
unsigned long long div(unsigned long long num,unsigned int divider){
unsigned int hi,lo;
to32bit(num,lo,hi);
lo = lo/divider;
hi = hi/divider;

Ну естественно так делить нельзя.
во 2 классе, кажется учат делить столбиком. Вот столбиком и нужно делить, а не каждую цифру.

Это тот случай, когда на асме сделать проще.
Код

unsigned long long div64 (unsigned long long num, unsigned int divider)
{
    int lo = (int)num;
    int hi = (int)(num >>32);

__asm{
    xor edx,edx
    mov eax, hi
    div divider
    push eax
    mov eax, lo
    div divider
    pop edx  
   } 
}

liveworkspace асма не понимает, (или я не знаю как там надо писать)
Проверил на студии выборочно, вроде работает


Если кто напишет на С/С++, тоже самое но короче, мое уважение, и плюс в репу!
(естественно без привлечения 64-разрядной арифметики)

Автор: x8m6 25.1.2012, 22:52
volatile, что то не робит. переменные lo и hi не изменяются вообще

Автор: volatile 25.1.2012, 23:10
x8m6, а они и не должны меняться.
результат функции в edx:eax
это и есть возврат функции unsigned long long func();

Автор: volatile 25.1.2012, 23:45
Ну если вам нужен результат в lo, hi (чтоб убедиться что работает)
Допишите в самом конце:
  mov hi, edx
  mov lo, eax

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)