PL/SQL function to receive a number and return its binary formatHow can I return the number of values in each row which match a criterion?Oracle extract slow function call from a WHERE clauseSQL Max() revision numberInserting into a table and getting the column names from a collection in PL/SQLHow to raise_application_error beyond a when others clauseWhat is a base64 RAW? How do I use it?How do I select a string valued field against a number less than X?Beginner PL/SQL: Return row value from dynamic SQL functionCustom return type of a function in Oracle PL SQlStore Function Value into temporary table
I've been given a project I can't complete, what should I do?
Sci-fi novel: ark ship from Earth is sent into space to another planet, one man woken early from cryosleep paints a giant mural
Is it expected that a reader will skip parts of what you write?
What is the logic behind taxing money for property?
Why am I Seeing A Weird "Notch" on the Data Line For Some Logical 1s?
Russian word for a male zebra
Is it safe to change the harddrive power feature so that it never turns off?
Next date with distinct digits
Fermat's statement about the ancients: How serious was he?
If I leave the US through an airport, do I have to return through the same airport?
Who won a Game of Bar Dice?
Can I utilise a baking stone to make crepes?
Non-aqueous eyes?
Will Roalesk, Apex Hybrid, trigger Sharktocrab twice?
Is there a set of positive integers of density 1 which contains no infinite arithmetic progression?
How to publish items after pipeline is finished?
What does a topology do, and what makes a particular topology the 'right' one?
If there's something that implicates the president why is there then a national security issue? (John Dowd)
Does the new finding on "reversing a quantum jump mid-flight" rule out any interpretations of QM?
Ability To Change Root User Password (Vulnerability?)
How can I protect this exterior outlet from water and prevent smoke leakage to the interior?
What standard algorithm can determine if exactly one of a container satisfies a predicate?
First sign that you should look for another job?
How to communicate to my GM that not being allowed to use stealth isn't fun for me?
PL/SQL function to receive a number and return its binary format
How can I return the number of values in each row which match a criterion?Oracle extract slow function call from a WHERE clauseSQL Max() revision numberInserting into a table and getting the column names from a collection in PL/SQLHow to raise_application_error beyond a when others clauseWhat is a base64 RAW? How do I use it?How do I select a string valued field against a number less than X?Beginner PL/SQL: Return row value from dynamic SQL functionCustom return type of a function in Oracle PL SQlStore Function Value into temporary table
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I'm trying to write a function to receive a number and return its binary format. This is what I've developed so far and it's ok for inputs : 4,8,16 but it does not return correct binary format for other numbers.
I could not find the problem and I was wondering if you could find the problem?
create or replace function Show_Binary(i_Number in Number) Return Varchar2
AS
V_Binary varchar2(50) := '';
i_Number2 Number := i_Number;
Begin
While i_Number2>=2 LOOP
V_Binary := V_Binary || Remainder(i_Number2, 2);
i_Number2 := i_Number2 / 2;
End LOOP;
V_Binary := V_Binary || TO_CHAR(i_Number2);
select reverse (V_Binary) into V_Binary from dual;
return (V_Binary);
End;
oracle oracle-11g plsql
add a comment |
I'm trying to write a function to receive a number and return its binary format. This is what I've developed so far and it's ok for inputs : 4,8,16 but it does not return correct binary format for other numbers.
I could not find the problem and I was wondering if you could find the problem?
create or replace function Show_Binary(i_Number in Number) Return Varchar2
AS
V_Binary varchar2(50) := '';
i_Number2 Number := i_Number;
Begin
While i_Number2>=2 LOOP
V_Binary := V_Binary || Remainder(i_Number2, 2);
i_Number2 := i_Number2 / 2;
End LOOP;
V_Binary := V_Binary || TO_CHAR(i_Number2);
select reverse (V_Binary) into V_Binary from dual;
return (V_Binary);
End;
oracle oracle-11g plsql
add a comment |
I'm trying to write a function to receive a number and return its binary format. This is what I've developed so far and it's ok for inputs : 4,8,16 but it does not return correct binary format for other numbers.
I could not find the problem and I was wondering if you could find the problem?
create or replace function Show_Binary(i_Number in Number) Return Varchar2
AS
V_Binary varchar2(50) := '';
i_Number2 Number := i_Number;
Begin
While i_Number2>=2 LOOP
V_Binary := V_Binary || Remainder(i_Number2, 2);
i_Number2 := i_Number2 / 2;
End LOOP;
V_Binary := V_Binary || TO_CHAR(i_Number2);
select reverse (V_Binary) into V_Binary from dual;
return (V_Binary);
End;
oracle oracle-11g plsql
I'm trying to write a function to receive a number and return its binary format. This is what I've developed so far and it's ok for inputs : 4,8,16 but it does not return correct binary format for other numbers.
I could not find the problem and I was wondering if you could find the problem?
create or replace function Show_Binary(i_Number in Number) Return Varchar2
AS
V_Binary varchar2(50) := '';
i_Number2 Number := i_Number;
Begin
While i_Number2>=2 LOOP
V_Binary := V_Binary || Remainder(i_Number2, 2);
i_Number2 := i_Number2 / 2;
End LOOP;
V_Binary := V_Binary || TO_CHAR(i_Number2);
select reverse (V_Binary) into V_Binary from dual;
return (V_Binary);
End;
oracle oracle-11g plsql
oracle oracle-11g plsql
edited Jun 2 at 10:54
Colin 't Hart
6,75782634
6,75782634
asked Jun 2 at 9:00
Pantea TourangPantea Tourang
40411
40411
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
This is not an Oracle or PL/SQL issue, but a matter of implementing the proper algorithm.
Here is an example:
https://www.orafaq.com/wiki/Binary
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> SELECT dec2bin(22) FROM dual;
DEC2BIN(22)
----------------
10110
The overhead of LISTAGG + hierarchical query + other SQL functions is bigger than the overhead of a simple PL/SQL function.
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:13.75
with g as (select * from dual connect by level <= 1000),
g2 as (select rownum as r from g, g)
select count(distinct bin) as bincd from (
select (SELECT LISTAGG(SIGN(BITAND(r, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=r
) as bin
from g2
);
BINCD
----------
1000000
Elapsed: 00:00:35.53
And this is without the UDF Pragma. On 12c and above the usage of the function gets slightly faster with the addition of PRAGMA_UDF
.
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
PRAGMA UDF; -- <==================================================== MAGIC
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:12.01
1
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
1
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
1
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
1
Just a note,MOD()
works properly only up to numbers 2**127.
– Wernfried Domscheit
Jun 3 at 6:29
1
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
|
show 1 more comment
No need to use a function - you can do it in (Oracle's) SQL.
SELECT LISTAGG(SIGN(BITAND(43, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=43;
Result:
BIN
101011
I found this deadly snippet here and the fiddle is here. For the number 43, just substitute your column of choice. It's probably possible to do this using recursive CTE
s, but that's a bit above my pay grade :-).
And to reverse the process, you can use this snippet
WITH INPUT AS
(SELECT REVERSE('1000') AS X FROM DUAL)
SELECT SUM(TO_NUMBER(SUBSTR(X,LEVEL,1)*POWER(2,LEVEL-1))) AS OUTPUT
FROM INPUT CONNECT BY LEVEL<=LENGTH(X);
Result:
OUTPUT
8
From here - dbfiddle here. Again, a recursive CTE
might do the trick. Again, for '1000', just substitute your column.
Just for kicks, I found another function which will work (with tweaks) on older versions of databases that don't have recursive CTEs. From the excellent Orafaq site here.
SELECT
DECODE(BITAND(VALUE, 128), 128, '1', '0') ||
DECODE(BITAND(VALUE, 64), 64, '1', '0') ||
DECODE(BITAND(VALUE, 32), 32, '1', '0') ||
DECODE(BITAND(VALUE, 16), 16, '1', '0') ||
DECODE(BITAND(VALUE, 8), 8, '1', '0') ||
DECODE(BITAND(VALUE, 4), 4, '1', '0') ||
DECODE(BITAND(VALUE, 2), 2, '1', '0') ||
DECODE(BITAND(VALUE, 1), 1, '1', '0') as bin_number from
(select 8 as value from dual) A;
Result:
MY_BIN
1000
Fiddle here. The more observant among you will notice that that code does not remove leading zeros - the code above has to be encase (entombed?) in this snippet
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
which can be found here.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "182"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f239646%2fpl-sql-function-to-receive-a-number-and-return-its-binary-format%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is not an Oracle or PL/SQL issue, but a matter of implementing the proper algorithm.
Here is an example:
https://www.orafaq.com/wiki/Binary
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> SELECT dec2bin(22) FROM dual;
DEC2BIN(22)
----------------
10110
The overhead of LISTAGG + hierarchical query + other SQL functions is bigger than the overhead of a simple PL/SQL function.
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:13.75
with g as (select * from dual connect by level <= 1000),
g2 as (select rownum as r from g, g)
select count(distinct bin) as bincd from (
select (SELECT LISTAGG(SIGN(BITAND(r, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=r
) as bin
from g2
);
BINCD
----------
1000000
Elapsed: 00:00:35.53
And this is without the UDF Pragma. On 12c and above the usage of the function gets slightly faster with the addition of PRAGMA_UDF
.
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
PRAGMA UDF; -- <==================================================== MAGIC
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:12.01
1
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
1
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
1
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
1
Just a note,MOD()
works properly only up to numbers 2**127.
– Wernfried Domscheit
Jun 3 at 6:29
1
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
|
show 1 more comment
This is not an Oracle or PL/SQL issue, but a matter of implementing the proper algorithm.
Here is an example:
https://www.orafaq.com/wiki/Binary
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> SELECT dec2bin(22) FROM dual;
DEC2BIN(22)
----------------
10110
The overhead of LISTAGG + hierarchical query + other SQL functions is bigger than the overhead of a simple PL/SQL function.
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:13.75
with g as (select * from dual connect by level <= 1000),
g2 as (select rownum as r from g, g)
select count(distinct bin) as bincd from (
select (SELECT LISTAGG(SIGN(BITAND(r, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=r
) as bin
from g2
);
BINCD
----------
1000000
Elapsed: 00:00:35.53
And this is without the UDF Pragma. On 12c and above the usage of the function gets slightly faster with the addition of PRAGMA_UDF
.
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
PRAGMA UDF; -- <==================================================== MAGIC
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:12.01
1
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
1
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
1
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
1
Just a note,MOD()
works properly only up to numbers 2**127.
– Wernfried Domscheit
Jun 3 at 6:29
1
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
|
show 1 more comment
This is not an Oracle or PL/SQL issue, but a matter of implementing the proper algorithm.
Here is an example:
https://www.orafaq.com/wiki/Binary
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> SELECT dec2bin(22) FROM dual;
DEC2BIN(22)
----------------
10110
The overhead of LISTAGG + hierarchical query + other SQL functions is bigger than the overhead of a simple PL/SQL function.
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:13.75
with g as (select * from dual connect by level <= 1000),
g2 as (select rownum as r from g, g)
select count(distinct bin) as bincd from (
select (SELECT LISTAGG(SIGN(BITAND(r, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=r
) as bin
from g2
);
BINCD
----------
1000000
Elapsed: 00:00:35.53
And this is without the UDF Pragma. On 12c and above the usage of the function gets slightly faster with the addition of PRAGMA_UDF
.
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
PRAGMA UDF; -- <==================================================== MAGIC
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:12.01
This is not an Oracle or PL/SQL issue, but a matter of implementing the proper algorithm.
Here is an example:
https://www.orafaq.com/wiki/Binary
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> SELECT dec2bin(22) FROM dual;
DEC2BIN(22)
----------------
10110
The overhead of LISTAGG + hierarchical query + other SQL functions is bigger than the overhead of a simple PL/SQL function.
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:13.75
with g as (select * from dual connect by level <= 1000),
g2 as (select rownum as r from g, g)
select count(distinct bin) as bincd from (
select (SELECT LISTAGG(SIGN(BITAND(r, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=r
) as bin
from g2
);
BINCD
----------
1000000
Elapsed: 00:00:35.53
And this is without the UDF Pragma. On 12c and above the usage of the function gets slightly faster with the addition of PRAGMA_UDF
.
CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
PRAGMA UDF; -- <==================================================== MAGIC
binval varchar2(64);
N2 number := N;
BEGIN
while ( N2 > 0 ) loop
binval := mod(N2, 2) || binval;
N2 := trunc( N2 / 2 );
end loop;
return binval;
END dec2bin;
/
SQL> with g as (select * from dual connect by level <= 1000) select count(distinct dec2bin(rownum)) as bincd from g,g;
BINCD
----------
1000000
Elapsed: 00:00:12.01
edited Jun 2 at 10:44
answered Jun 2 at 9:06
Balazs PappBalazs Papp
27.6k21032
27.6k21032
1
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
1
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
1
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
1
Just a note,MOD()
works properly only up to numbers 2**127.
– Wernfried Domscheit
Jun 3 at 6:29
1
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
|
show 1 more comment
1
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
1
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
1
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
1
Just a note,MOD()
works properly only up to numbers 2**127.
– Wernfried Domscheit
Jun 3 at 6:29
1
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
1
1
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
Szia @BalazsPapp - I know that you're pretty hot with Oracle - would it not be better to use SQL as per my answer - I seem to have read that performance-wise, it's better to use SQL first, then PL/SQL? Does Oracle do pure binary arithmatic without moving back and forth between strings?
– Vérace
Jun 2 at 9:52
1
1
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
@Vérace That is typically true when someone does row-by-row processing in PL/SQL instead of pure SQL. But that is not a general truth, see my update.
– Balazs Papp
Jun 2 at 10:46
1
1
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
@BalazsPapp - thanks for that explanation. Obviously rules of thumb are not universal truths! :-) I'll try and bear that in mind. I'd love to have Tom Kyte's runstats to hand to really drill down on this issue - but, so many intereting questions, so little time! :-)
– Vérace
Jun 2 at 10:58
1
1
Just a note,
MOD()
works properly only up to numbers 2**127.– Wernfried Domscheit
Jun 3 at 6:29
Just a note,
MOD()
works properly only up to numbers 2**127.– Wernfried Domscheit
Jun 3 at 6:29
1
1
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
When my factory is producting its ( (2**127) + 1 )-th widget, I'll start to worry! :-)
– Vérace
Jun 3 at 10:51
|
show 1 more comment
No need to use a function - you can do it in (Oracle's) SQL.
SELECT LISTAGG(SIGN(BITAND(43, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=43;
Result:
BIN
101011
I found this deadly snippet here and the fiddle is here. For the number 43, just substitute your column of choice. It's probably possible to do this using recursive CTE
s, but that's a bit above my pay grade :-).
And to reverse the process, you can use this snippet
WITH INPUT AS
(SELECT REVERSE('1000') AS X FROM DUAL)
SELECT SUM(TO_NUMBER(SUBSTR(X,LEVEL,1)*POWER(2,LEVEL-1))) AS OUTPUT
FROM INPUT CONNECT BY LEVEL<=LENGTH(X);
Result:
OUTPUT
8
From here - dbfiddle here. Again, a recursive CTE
might do the trick. Again, for '1000', just substitute your column.
Just for kicks, I found another function which will work (with tweaks) on older versions of databases that don't have recursive CTEs. From the excellent Orafaq site here.
SELECT
DECODE(BITAND(VALUE, 128), 128, '1', '0') ||
DECODE(BITAND(VALUE, 64), 64, '1', '0') ||
DECODE(BITAND(VALUE, 32), 32, '1', '0') ||
DECODE(BITAND(VALUE, 16), 16, '1', '0') ||
DECODE(BITAND(VALUE, 8), 8, '1', '0') ||
DECODE(BITAND(VALUE, 4), 4, '1', '0') ||
DECODE(BITAND(VALUE, 2), 2, '1', '0') ||
DECODE(BITAND(VALUE, 1), 1, '1', '0') as bin_number from
(select 8 as value from dual) A;
Result:
MY_BIN
1000
Fiddle here. The more observant among you will notice that that code does not remove leading zeros - the code above has to be encase (entombed?) in this snippet
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
which can be found here.
add a comment |
No need to use a function - you can do it in (Oracle's) SQL.
SELECT LISTAGG(SIGN(BITAND(43, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=43;
Result:
BIN
101011
I found this deadly snippet here and the fiddle is here. For the number 43, just substitute your column of choice. It's probably possible to do this using recursive CTE
s, but that's a bit above my pay grade :-).
And to reverse the process, you can use this snippet
WITH INPUT AS
(SELECT REVERSE('1000') AS X FROM DUAL)
SELECT SUM(TO_NUMBER(SUBSTR(X,LEVEL,1)*POWER(2,LEVEL-1))) AS OUTPUT
FROM INPUT CONNECT BY LEVEL<=LENGTH(X);
Result:
OUTPUT
8
From here - dbfiddle here. Again, a recursive CTE
might do the trick. Again, for '1000', just substitute your column.
Just for kicks, I found another function which will work (with tweaks) on older versions of databases that don't have recursive CTEs. From the excellent Orafaq site here.
SELECT
DECODE(BITAND(VALUE, 128), 128, '1', '0') ||
DECODE(BITAND(VALUE, 64), 64, '1', '0') ||
DECODE(BITAND(VALUE, 32), 32, '1', '0') ||
DECODE(BITAND(VALUE, 16), 16, '1', '0') ||
DECODE(BITAND(VALUE, 8), 8, '1', '0') ||
DECODE(BITAND(VALUE, 4), 4, '1', '0') ||
DECODE(BITAND(VALUE, 2), 2, '1', '0') ||
DECODE(BITAND(VALUE, 1), 1, '1', '0') as bin_number from
(select 8 as value from dual) A;
Result:
MY_BIN
1000
Fiddle here. The more observant among you will notice that that code does not remove leading zeros - the code above has to be encase (entombed?) in this snippet
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
which can be found here.
add a comment |
No need to use a function - you can do it in (Oracle's) SQL.
SELECT LISTAGG(SIGN(BITAND(43, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=43;
Result:
BIN
101011
I found this deadly snippet here and the fiddle is here. For the number 43, just substitute your column of choice. It's probably possible to do this using recursive CTE
s, but that's a bit above my pay grade :-).
And to reverse the process, you can use this snippet
WITH INPUT AS
(SELECT REVERSE('1000') AS X FROM DUAL)
SELECT SUM(TO_NUMBER(SUBSTR(X,LEVEL,1)*POWER(2,LEVEL-1))) AS OUTPUT
FROM INPUT CONNECT BY LEVEL<=LENGTH(X);
Result:
OUTPUT
8
From here - dbfiddle here. Again, a recursive CTE
might do the trick. Again, for '1000', just substitute your column.
Just for kicks, I found another function which will work (with tweaks) on older versions of databases that don't have recursive CTEs. From the excellent Orafaq site here.
SELECT
DECODE(BITAND(VALUE, 128), 128, '1', '0') ||
DECODE(BITAND(VALUE, 64), 64, '1', '0') ||
DECODE(BITAND(VALUE, 32), 32, '1', '0') ||
DECODE(BITAND(VALUE, 16), 16, '1', '0') ||
DECODE(BITAND(VALUE, 8), 8, '1', '0') ||
DECODE(BITAND(VALUE, 4), 4, '1', '0') ||
DECODE(BITAND(VALUE, 2), 2, '1', '0') ||
DECODE(BITAND(VALUE, 1), 1, '1', '0') as bin_number from
(select 8 as value from dual) A;
Result:
MY_BIN
1000
Fiddle here. The more observant among you will notice that that code does not remove leading zeros - the code above has to be encase (entombed?) in this snippet
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
which can be found here.
No need to use a function - you can do it in (Oracle's) SQL.
SELECT LISTAGG(SIGN(BITAND(43, POWER(2,LEVEL-1))),'')
WITHIN GROUP(ORDER BY LEVEL DESC) bin
FROM dual
CONNECT BY POWER(2, LEVEL-1)<=43;
Result:
BIN
101011
I found this deadly snippet here and the fiddle is here. For the number 43, just substitute your column of choice. It's probably possible to do this using recursive CTE
s, but that's a bit above my pay grade :-).
And to reverse the process, you can use this snippet
WITH INPUT AS
(SELECT REVERSE('1000') AS X FROM DUAL)
SELECT SUM(TO_NUMBER(SUBSTR(X,LEVEL,1)*POWER(2,LEVEL-1))) AS OUTPUT
FROM INPUT CONNECT BY LEVEL<=LENGTH(X);
Result:
OUTPUT
8
From here - dbfiddle here. Again, a recursive CTE
might do the trick. Again, for '1000', just substitute your column.
Just for kicks, I found another function which will work (with tweaks) on older versions of databases that don't have recursive CTEs. From the excellent Orafaq site here.
SELECT
DECODE(BITAND(VALUE, 128), 128, '1', '0') ||
DECODE(BITAND(VALUE, 64), 64, '1', '0') ||
DECODE(BITAND(VALUE, 32), 32, '1', '0') ||
DECODE(BITAND(VALUE, 16), 16, '1', '0') ||
DECODE(BITAND(VALUE, 8), 8, '1', '0') ||
DECODE(BITAND(VALUE, 4), 4, '1', '0') ||
DECODE(BITAND(VALUE, 2), 2, '1', '0') ||
DECODE(BITAND(VALUE, 1), 1, '1', '0') as bin_number from
(select 8 as value from dual) A;
Result:
MY_BIN
1000
Fiddle here. The more observant among you will notice that that code does not remove leading zeros - the code above has to be encase (entombed?) in this snippet
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
which can be found here.
edited Jun 3 at 11:03
answered Jun 2 at 9:49
VéraceVérace
16.9k33653
16.9k33653
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f239646%2fpl-sql-function-to-receive-a-number-and-return-its-binary-format%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown