That is the way you'll need to do it, however, you could take advantage of Oracle removing parts of the SQL from consideration as early as possible.
For example, you could build a single SQL dynamically with ALL of the partitions
select * from table partition (sys_t1)
union all
...
select * from table partition (sys_t9)
union all
select * from table partition (sys_t10)
and then add a bind variable to each one, ie
select * from table partition (sys_t1) where bitand(:bindvar,1) = 1
union all
...
select * from table partition (sys_t9) where bitand(:bindvar,2) = 2
union all
select * from table partition (sys_t10) where bitand(:bindvar,4) = 4
etc etc
and then some bitwise logic to get whatever partitions you want.
If I explain that query, you can see that we do FILTER before each partition access, so we decide by looking at the bind variable before deciding whether to visit that partition
SQL> set autotrace traceonly explain
SQL> select *
2 from
3 (
4 select * from t partition ( SYS_P1537 ) where bitand(:b,1) = 1 union all
5 select * from t partition ( SYS_P1538 ) where bitand(:b,2) = 2 union all
6 select * from t partition ( SYS_P1539 ) where bitand(:b,4) = 4 union all
7 select * from t partition ( SYS_P1540 ) where bitand(:b,8) = 8 union all
8 select * from t partition ( SYS_P1541 ) where bitand(:b,16) = 16 union all
9 select * from t partition ( SYS_P1542 ) where bitand(:b,32) = 32 union all
10 select * from t partition ( SYS_P1543 ) where bitand(:b,64) = 64 union all
11 select * from t partition ( SYS_P1544 ) where bitand(:b,128) = 128
12 )
13 /
Execution Plan
----------------------------------------------------------
Plan hash value: 2067716848
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1026K| 25M| 618 (1)| 00:00:01 | | |
| 1 | VIEW | | 1026K| 25M| 618 (1)| 00:00:01 | | |
| 2 | UNION-ALL | | | | | | | |
|* 3 | FILTER | | | | | | | |
| 4 | PARTITION HASH SINGLE| | 112K| 2867K| 77 (0)| 00:00:01 | 1 | 1 |
| 5 | TABLE ACCESS FULL | T | 112K| 2867K| 77 (0)| 00:00:01 | 1 | 1 |
|* 6 | FILTER | | | | | | | |
| 7 | PARTITION HASH SINGLE| | 124K| 3149K| 77 (0)| 00:00:01 | 2 | 2 |
| 8 | TABLE ACCESS FULL | T | 124K| 3149K| 77 (0)| 00:00:01 | 2 | 2 |
|* 9 | FILTER | | | | | | | |
| 10 | PARTITION HASH SINGLE| | 120K| 3056K| 77 (0)| 00:00:01 | 3 | 3 |
| 11 | TABLE ACCESS FULL | T | 120K| 3056K| 77 (0)| 00:00:01 | 3 | 3 |
|* 12 | FILTER | | | | | | | |
| 13 | PARTITION HASH SINGLE| | 123K| 3136K| 77 (0)| 00:00:01 | 4 | 4 |
| 14 | TABLE ACCESS FULL | T | 123K| 3136K| 77 (0)| 00:00:01 | 4 | 4 |
|* 15 | FILTER | | | | | | | |
| 16 | PARTITION HASH SINGLE| | 146K| 3728K| 77 (0)| 00:00:01 | 5 | 5 |
| 17 | TABLE ACCESS FULL | T | 146K| 3728K| 77 (0)| 00:00:01 | 5 | 5 |
|* 18 | FILTER | | | | | | | |
| 19 | PARTITION HASH SINGLE| | 144K| 3675K| 77 (0)| 00:00:01 | 6 | 6 |
| 20 | TABLE ACCESS FULL | T | 144K| 3675K| 77 (0)| 00:00:01 | 6 | 6 |
|* 21 | FILTER | | | | | | | |
| 22 | PARTITION HASH SINGLE| | 120K| 3063K| 77 (0)| 00:00:01 | 7 | 7 |
| 23 | TABLE ACCESS FULL | T | 120K| 3063K| 77 (0)| 00:00:01 | 7 | 7 |
|* 24 | FILTER | | | | | | | |
| 25 | PARTITION HASH SINGLE| | 133K| 3394K| 77 (0)| 00:00:01 | 8 | 8 |
| 26 | TABLE ACCESS FULL | T | 133K| 3394K| 77 (0)| 00:00:01 | 8 | 8 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(BITAND(TO_NUMBER(:B),1)=1)
6 - filter(BITAND(TO_NUMBER(:B),2)=2)
9 - filter(BITAND(TO_NUMBER(:B),4)=4)
12 - filter(BITAND(TO_NUMBER(:B),8)=8)
15 - filter(BITAND(TO_NUMBER(:B),16)=16)
18 - filter(BITAND(TO_NUMBER(:B),32)=32)
21 - filter(BITAND(TO_NUMBER(:B),64)=64)
24 - filter(BITAND(TO_NUMBER(:B),128)=128)