LINUX.ORG.RU

Ответ на: комментарий от jtootf

2 ТС: главное не забыть флаг оптимизации добавить

lester ★★★★
()

Зависит от компилятор и может быть даже от процессора. Вообще, в моём представлении первое должно происходить без участия сопроцессора, а второе — с участием (если без оптимизаций), поэтому зависит от того, что быстрее.

vkos ★★
()

П.С. return std::signbit(x) ? -1 : 1;
П.П.С. кроме более читабельной записи надо следовать правилу, что желательно в функции иметь только один return

lester ★★★★
()
Ответ на: комментарий от vkos

Просто там всё равно jump'ы будут.

Будут, но короткие:

#include <stdio.h>

main(){
double l = 10.0;
int s = (l < 0.) ? -1:1;
printf("l=%f, s=%d\n", l, s);
}	.file	"1.c"
	.section	.rodata
.LC2:
	.string	"l=%f, s=%d\n"
	.text
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ecx
	subl	$52, %esp
	fldl	.LC0
	fstpl	-24(%ebp)
	fldl	-24(%ebp)
	fldz
	fucompp
	fnstsw	%ax
	sahf
	jbe	.L7
.L6:
	movl	$-1, -28(%ebp)
	jmp	.L4
.L7:
	movl	$1, -28(%ebp)
.L4:
	movl	-28(%ebp), %eax
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	movl	%eax, 12(%esp)
	fldl	-24(%ebp)
	fstpl	4(%esp)
	movl	$.LC2, (%esp)
	call	printf
	addl	$52, %esp
	popl	%ecx
	popl	%ebp
	leal	-4(%ecx), %esp
	ret
	.size	main, .-main
	.section	.rodata
	.align 8
.LC0:
	.long	0
	.long	1076101120
	.ident	"GCC: (GNU) 4.3.2"
	.section	.note.GNU-stack,"",@progbits
cat 2.c 2.s
#include <stdio.h>

int sign(double l){
	return (l < 0.) ? -1:1;
}
main(){
double l = 10.0;
int s = sign(l);
printf("l=%f, s=%d\n", l, s);
}	.file	"2.c"
	.text
.globl sign
	.type	sign, @function
sign:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$16, %esp
	movl	8(%ebp), %eax
	movl	%eax, -8(%ebp)
	movl	12(%ebp), %eax
	movl	%eax, -4(%ebp)
	fldl	-8(%ebp)
	fldz
	fucompp
	fnstsw	%ax
	sahf
	jbe	.L7
.L6:
	movl	$-1, -12(%ebp)
	jmp	.L4
.L7:
	movl	$1, -12(%ebp)
.L4:
	movl	-12(%ebp), %eax
	leave
	ret
	.size	sign, .-sign
	.section	.rodata
.LC3:
	.string	"l=%f, s=%d\n"
	.text
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ecx
	subl	$52, %esp
	fldl	.LC2
	fstpl	-24(%ebp)
	fldl	-24(%ebp)
	fstpl	(%esp)
	call	sign
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	movl	%eax, 12(%esp)
	fldl	-24(%ebp)
	fstpl	4(%esp)
	movl	$.LC3, (%esp)
	call	printf
	addl	$52, %esp
	popl	%ecx
	popl	%ebp
	leal	-4(%ecx), %esp
	ret
	.size	main, .-main
	.section	.rodata
	.align 8
.LC2:
	.long	0
	.long	1076101120
	.ident	"GCC: (GNU) 4.3.2"
	.section	.note.GNU-stack,"",@progbits

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от linuxfan

>The CMOVcc instructions are new for the Pentium® Pro processor family; however, they may not be supported by all the processors in the family.

Так что gcc вряд ли будет его использовать. Да и потом, вроде как с double не должен работать (костыль то можно сделать, но без оптимизации вряд ли будет).

vkos ★★
()
Ответ на: комментарий от anonymous
int a1(double x)
{
	return 1 - (*(reinterpret_cast<uint64_t*>(&x)) & ((uint64_t)1<<63)) >> 62;
}
	movsd	%xmm0, -8(%rsp)
	movq	-8(%rsp), %rdx
	movabsq	$-9223372036854775808, %rax
	andq	%rax, %rdx
	movl	$1, %eax
	subq	%rdx, %rax
	shrq	$62, %rax
	ret

-------------------------------------

int a2(double d)
{
	if (d >= 0) return 1; else return -1;
}
	ucomisd	.LC0(%rip), %xmm0
	sbbl	%eax, %eax
	orl	$1, %eax
	ret
anonymous
()
Ответ на: комментарий от Eddy_Em

>>знаковый бит старший.

а если big-endian?

Хаха, такие спецы :) Он всегда старший хоть на мидлэндиан. Это всего лишь повлияет на то как данные хранятся в памяти.

anonymous
()
Ответ на: комментарий от anonymous

Тогда можно:

[code] return x >> sizeof(x); [/code]

anonymous
()
Ответ на: комментарий от lester

П.П.С. кроме более читабельной записи надо следовать правилу, что желательно в функции иметь только один return

На x86 ?: в cmov завернётся.

mv ★★★★★
()

А что с [code] return (x > 0 ? 1 : -1);[/code] ?

(Вариант x == 0 как я понял, считается несуществующим?)

sv75 ★★★★★
()
Ответ на: комментарий от sv75

код

if (d >= 0) return 1; else return -1;
и код
return (d >= 0 ? 1 : -1);
получаются в абсолютно одинаковые инструкции в GCC
	ucomisd	.LC0(%rip), %xmm0
	sbbl	%eax, %eax
	orl	$1, %eax
	ret

anonymous
()
Ответ на: комментарий от sv75

> (Вариант x == 0 как я понял, считается несуществующим?)

может соответствовать или -1, или +1 — не важно

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от vkos

Зависит от компилятор и может быть даже от процессора. Вообще, в моём представлении первое должно происходить без участия сопроцессора, а второе — с участием (если без оптимизаций), поэтому зависит от того, что быстрее.

И от контекста зависит. Потому что если определить знак числа нужно где-то посередине вычислений, то быстрее с помощью сопроцессора, так как число уже в одном из его регистров и выгружать его в память не выгодно. Если же надо определить знак у числа, которое получено когда-то давно, то быстрее взять у него значение отдельного бита.

Deleted
()
Ответ на: комментарий от JackyTreehorn

есть разница между проверкой входных данных и их обработкой, несколько точек выхода при обработке - вероятная утечка ресурсов

П.С. а сайт жутко авторитетный - ага

lester ★★★★
()
Ответ на: комментарий от lester

> несколько точек выхода при обработке - вероятная утечка ресурсов
RAII. В заголовке стоит [C++].

а сайт жутко авторитетный - ага

Таки да. Кроме того, там есть ссылки на весьма авторитетных авторитетов.

JackyTreehorn
()
Ответ на: комментарий от lester

А программы это гуманитарщина, чтобы авторитетам в рот заглядывать? Не лучше ли пользоваться логикой?

anonymous
()
Ответ на: комментарий от JackyTreehorn

Своей логики нет анализировать разные мнения? Надо всё делать как авторитет сказал?

anonymous
()
Ответ на: комментарий от anonymous

> Не лучше ли пользоваться логикой?

кажется я привел аргумент, ну раз на вторитетов не смотрим, то относительно того же RAII есть еще один аргумент - есть масса сторонних библиотек, которые надо использовать, сомневаюсь, что хоть один вменяемый человек будет писать обертки на каждый вызов

lester ★★★★
()
Ответ на: комментарий от JackyTreehorn

Это в философии может быть школа одноретурнов и школа многоретурнов с томами словесного поноса на эту тему. А в программах должно быть логическое обоснование, а логика не зависит от авторитетности её излагающего.

anonymous
()
Ответ на: комментарий от anonymous

Ну да, авторитеты ведь никогда не аргументируют, почему нужно делать так, а не иначе. Самому-то не смешно? Пора уже остепениться.

JackyTreehorn
()
Ответ на: комментарий от lester

Если это существенно облегчит жизнь в дальнейшем, почему бы и нет? Если задача сделать код exception safe, то почти обязательно.

JackyTreehorn
()
Ответ на: комментарий от JackyTreehorn

> Если это существенно облегчит жизнь в дальнейшем, почему бы и нет?

т.е. вы к любой сишной библиотеке пишете свою обвязку?

lester ★★★★
()
Ответ на: комментарий от JackyTreehorn

В их рассуждениях не рассматриваются все ситуации

Опровержение «одноретурнов»

if (!a.Ready())
  return -1;
if (!b.Ready())
  return -2;
if (!c.Ready())
  return -3;

//Работаем с a, b ,c

return 0;

Таким образом «многоретурность» необходима. «Одноретурность» является её частным случаем. Поэтому все общие рассуждения про 1 или несколько return идут на йух. Только конкретные ситуации можно рассматривать. А если кто-то раскорячивается в программах ради 1 return потому что так Сам Авторитет сказал, то такой кодер просто тупой дебил.

anonymous
()
Ответ на: комментарий от anonymous

if (!a.Ready())
return -1;
if (!b.Ready())
return -2;
if (!c.Ready())
return -3;
//Работаем с a, b ,c

я уже написал про то, что проверка входных условий - это отдельный случай, никак не связанный обработкой данных, если в твоем примере будет:

if( !( a = get_Data( 1 ) )
 return -1;

if( !( a = get_Data( 2 ) )
 return -2;

if( !( a = get_Data( 3 ) )
 return -3;

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

кто-то раскорячивается в программах ради 1 return

это ваша фантазия, я написал, что желательно иметь одну точку выхода, а не обязательно должна быть

lester ★★★★
()
Ответ на: комментарий от JackyTreehorn

И чё? Как ни назови это всё равно несколько return. Значит общий принцип «сдохни, но сделай только один ретурн» не действует.

anonymous
()
Ответ на: комментарий от lester

lester, такое ощущение,что вы программ то в жизни не писали, хех:-/

Вот, чтоб далеко не ходить, без всяких авторитетов, просто из жизни, возьмите любой лексический анализатор написанный на C. Примеров в репозитории GNU масса, и убедитесь.

Избегать многих ретурнов это то же, что и избегать continue, break, и goto - в некоторых случаях лишь запутывает.

(И вообще-достали эти сказки - одноретурность вам никак не поможет избежать даже и малой доли ваших утечек ресурсов, так практика показывает. Утечки возникают в ситуациях куда более изощрённых.)

В целом же, многоретурность естественна, это следствие использования анализа use case-ов, для проектирования ваших процедур. Избегать ее-это значит наживать себе лишние сложности из пустого места.

anonymous
()
Ответ на: комментарий от anonymous

* вручную написанный на С (без lex/flex).

anonymous
()
Ответ на: комментарий от lester

Лопухом не надо быть чтоб такое не писать.

Есть идиоматические конструкции, привычные всем, пользуйтесь ими.

Любой сможет написать while ((c = getchar()) != EOF) { ... }

Достали книги, в которых говорится, как нам следует писать программу. Но ни одной более-менее серьёзной программы не приводится. Последние 10 лет я только и занимаюсь, что анализирую чужой код с 18-00 до 00-00 и изучаю чужие методы проектирования, а с 08-00 до 16-00 пишу свой код, так что парни-не надо говорить мне, как я должен делать:-)

Школьные правила я много лет назад изучил (типа-см. например книгу Голуба), но одно только знание их не поможет вам работать с 10-метровым проектом. Здесь нужно знать почему правила получились такими, какие они есть, их природу изучить.

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

Если вы просто будете стремиться тупо выполнять правила подобные этим, то уподобитесь туземцам (см. Культ Карго) :-)

anonymous
()
Ответ на: комментарий от anonymous

уважаемый анонимус - я очень ценю ваше ЧСВ и то что вы так долго расписывали свое мнение, но:

1. «действительно, точка выхода как правило одна, и средняя длина не более 40 строк» - здорово, что вы это признали
2. примеры неудобности одноретурного подхода где? ( ес-но без учета проверки параметров )

lester ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.