писал я как то функцию округления....
так вот она округляла доублы,
как получалось это не правильным сопсобом так:
1)рпеобразовываем в строку
2)режем целое и дробь (строки)
3)формируем строки с ужетом округления:
— целое
— дробь
— перенос.
4)все строки конвертим в доубл и складываем
та вот при сложении трех доублов результат, который также был доубл иногда сбивался например с 3.37 на 3.3699999999999.....
так вот дело оказалось в том, что у не хватает точности доублов (с конца). и правильный выход в этом случае — складывать все в децимал, т.к. у него разрядность больше, а потом, через строку, можно конвертировать в доубл.
Здравствуйте, Scif, Вы писали:
S>Это с чего это Вы взяли? S>....
Есть такая штука как Рефлектор, вот с помощью него и посмотрел
Convert.ToString(byte) вызывает byte.ToString(), а он вызывает Number.FormatInt32(int, ...)
S>А это S>byte a = 0x25; S>не вызывает?
Это конечно не совсем корректное присваивание, но компилятор вполне себе справляется
Re[2]: Преобразование чисел в C#
От:
Аноним
Дата:
11.10.06 09:01
Оценка:
ну в таком случае и это тоже также
аботает
a.ToString("x") + b.ToString("x");
так что вопрос есть ли впринципе метод перевода байта в текс не использующий приведения в инт?
a.ToString("x") + b.ToString("x");
Это как раз дает правильный результат, модификатор "x" значит привести в шестнадцатеричный вид и 0x25 будет как "25", а 0x00 как "0". Вы сначала попробуйте, а потом говорите, если в своих знаниях не уверены.
Уважаемый, Вы слегка не правильно меня поняли,
я не говорю что работает не правильно.
НО, как уже заметил Alexey Ivanov,
и мой и Ваш вариант в конце концов обращаються к методу Number.FormatInt32(int, ...), передача параметров которому ведет к неявному преобразованию byte в int
и рефлектор это хорошо показывает.
Здравствуйте, ZeeM, Вы писали:
ZM>Что то не могу разобраться.
ZM>есть два числа ZM>byte a = 0x25; ZM>byte b = 0x00;
ZM>мне необходимо преобразовать это в строку "250"
ZM>варианты типа:
ZM>string temp = a.ToString() + b.ToString(); не катят, т.к. получаются что байты сначала преобразуются в int. Как сделать это корректно?
А , почему нельзя в int? Память экономим?
--------------------------
less think — do more
Преобразование чисел в C#
От:
Аноним
Дата:
11.10.06 09:58
Оценка:
Если родной byte.ToString() не подходит, самое время переходить на asm или стандартный С/С++.
Здравствуйте, Scif, Вы писали:
S>и мой и Ваш вариант в конце концов обращаються к методу Number.FormatInt32(int, ...), передача параметров которому ведет к неявному преобразованию byte в int
Это преобразование (byte в int32) будет выполняться всегда ибо так работает .Net.
Так как только для Int32 определены арифметические операции.
Как это не поакжется странным, но в:
byte a = 1;
byte b = 10;
a = b*2;
Оператор a = b*2; будет вызывать преобразование к Int32.
Здравствуйте, ZeeM, Вы писали:
ZM>string temp = a.ToString() + b.ToString(); не катят, т.к. получаются что байты сначала преобразуются в int. Как сделать это корректно?
Здравствуйте, Red Bird, Вы писали:
RB>Здравствуйте, Scif, Вы писали:
S>>и мой и Ваш вариант в конце концов обращаються к методу Number.FormatInt32(int, ...), передача параметров которому ведет к неявному преобразованию byte в int
RB>Это преобразование (byte в int32) будет выполняться всегда ибо так работает .Net. RB>Так как только для Int32 определены арифметические операции.
RB>Как это не поакжется странным, но в: RB>
RB>byte a = 1;
RB>byte b = 10;
RB>a = b*2;
RB>
RB>Оператор a = b*2; будет вызывать преобразование к Int32.
Это не кажется странным вовсе, потому что это делается для того, чтобы избежать потери данных при переполнении числа, ведь произведение может завалиться за диапазон байта.
Здравствуйте, Pavel M., Вы писали:
PM>Это не кажется странным вовсе, потому что это делается для того, чтобы избежать потери данных при переполнении числа, ведь произведение может завалиться за диапазон байта.
По твоей логике при умножении int-ов должно проводиться приведение к long-ам.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Преобразование чисел в C#
От:
Аноним
Дата:
11.10.06 12:11
Оценка:
Ваши бы слова,....
а почему тогда double+double=double, а не decimal?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Pavel M., Вы писали:
PM>>Это не кажется странным вовсе, потому что это делается для того, чтобы избежать потери данных при переполнении числа, ведь произведение может завалиться за диапазон байта.
L>По твоей логике при умножении int-ов должно проводиться приведение к long-ам.
если переполнение произойдет в checked контексте — OverflowException, если в unchecked — старшие биты, не помещающиеся в диапазон, отбрасываются.
а вообще существует ряд predefined операторов умножения для целых чисел
int operator *(int x, int y);
uint operator *(uint x, uint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);
при выполнении умножения выполняется поиск первого оператора из списка для которого существует неявное преобразование между фактическими и формальными типами операндов.
class Program
{
public static void Print<T>(T arg)
{
Console.WriteLine(typeof(T).FullName);
}
public static void Main()
{
byte a = 20;
short b = 30;
double c = 40;
Print(a * b); // System.Int32
Print(a * c); // System.Doublelong d = 50;
Print(c * d); // System.Doubleint f = 50;
Print(f * d); // System.Int64ulong e = 60;
//Print(d + e); // Operator '+' cannot be applied to operands of type 'long' and 'ulong'
}
}
Преобразование чисел в C#
От:
Аноним
Дата:
10.01.07 08:41
Оценка:
Я хренею, дорогая редакция...
Народ, есть в C# такое понятие, как литералы.
Например, 2 — это литерал. Он имеет тип Int32.
Т.е. если Вы напишете такой код:
long x = 2;
2 приведётся к Int32, а потом — к long.
Правильной будет такая запись:
// 2 уже имеет тип long
long x = 2L; // Оно даже компилируется!!!
И точно, чего это я сразу не заметил что ты доказательств то своих слов не привел. Показывай код на MSIL где мы увидим сначала приведение к инту а потом к лонгу
Под рукой студии нету. Попробуй вместо двойки взять скажем 35. Для двойки есть отдельная инструкция ldc.i4.2 похожей интсрукции ldc.i8.2 нету. Для чисел от 0 до 8 специнструкций не наблюдается, так что с 35 ему не удастся так легко отвертеться. В общем компилер наоптимизировал таки.
Хм. Всетаки на интах не интересно проверять, думаю что для 35 и 35L все равно будет один и тот же код: ldc.i4 35 с последующим conv.i8 по одной простой причине, а именно оптимизация, эти две команды элементарно в байтах будут меньше чем ldc.i8 и дело даже не будет тут ни в каких литералах.
Интересные эксперименты:
static void Main(string[] args)
{
const long x=35;
const long xl=35L;
int y=x;
int yl=xl;
Console.WriteLine((y * yl).ToString());
}
Будут ли тут лишние преобразования, можно еще попробовать с даблами, чтобы добиться явного вызова ToIn32 из литералов.
В общем нет никакого смысла ЯВНО указывать L после цифири, мозгов компилятору и своих хватает.
Хм. а интересно что он там накомпилирует на int x=100000L и int x=100000 будет хоть что-то отличаться?
Видно, что байты хранятся в 4 байтовых ячейках. Но это нормально в 32-х разрядных системах.
-------------------------------------------------
2 ZeeM: 0x25 — это 37 в человеческой системе измерения. Поэтому (может, кто-то уже предлагал) надо делать правильное форматирование (http://msdn2.microsoft.com/en-us/library/dwhawy9k.aspx):
byte a = 0x25;
byte b = 0x00;
string temp = a.ToString("x") + b.ToString("x");
БУДЕТ КАК РАЗ ТО, ЧТО НУЖНО!
-------------------------------------------------
2 RuneLord:
С какой стати я должен ему доверять?
Microsoft редко делает что-то хорошее.
Как Ты делал человеческое форматирование кода в своём сообщении (цвета там, отступы)?